简体   繁体   中英

Select many rows by unique columns with good performance

I want to select about 20 to 100 rows from a table using four columns which make up an unique index.

The first approach I came up with was using OR :

SELECT ...
WHERE (w_id = ? AND type_id = ? AND object_id = ? AND part_name = ?)
   OR (w_id = ? AND type_id = ? AND object_id = ? AND part_name = ?)
   OR [...]

I've also seen a solution using row constructors:

SELECT ...
WHERE (w_id, type_id, object_id, part_name) IN ((1,2,3,''),(1,2,4,''), [...])

However, it was said that this has a bad performance when selecting many rows.

Which solution has the better performance or should I use an other solution (such as splitting the queries)?

Thanks in advance!

Table structure

CREATE TABLE page(
    page_id PRIMARY KEY AUTO_INCREMENT,
    w_id INTEGER NOT NULL,
    ns_id INTEGER NOT NULL,
    type_id INTEGER NOT NULL,
    object_id INTEGER NOT NULL,
    part_name VARCHAR(20) NOT NULL,
);

Both w_id and ns_id are foreign keys.

There is only one index, which is the unique index containing the columns w_id , type_id , object_id and part_name .

Measurement

I filled the table with about 700k rows and ran three querys (also one with using UNION ). I always queried for the same rows. These are the results:

Solution  Time [s]  EXPLAIN
with OR   0.0003    ref
with IN   0.4546    ALL
UNION     0.0004    const

Raymond's presumption that using an IN could cause a full table scan was proved. However, the results show that OR and UNION show quite the same time.

What also makes me worry is the fact that these results only were achieved after a defragmentation. Before the defragmentation even the solution with OR took about 0.3 s.

Selecting using = , AND and OR / UNION ALL works faster than using IN in combination with row constructor. IN forces a full table scan which makes it a few times slower than the other solution.

However, on the recommendation of wildplasser:

"the need for UNION and/or AND/OR clauses are often the result of a sub-optimal data model"

I will change my data base model so there is no need for selecting the rows in this way but rather I'll use a join.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM