简体   繁体   中英

How to choose correct index for SQL query with ORDER BY clause (MySQL)

I have a query in MySQL that looks something like this:

SELECT t.field1, t.field2, t.field5, t.field6, t.field7 
FROM mytable as t  

WHERE t.field1 = a AND t.field2 = b AND t.field3 = c AND LENGTH(t.field4) > 0

order by t.field5 desc

LIMIT 0, 100;

The query is not very fast (10 seconds) and the problem seems to be the ORDER BY part, without that line the query takes 0.01 seconds, using ASC instead of desc takes about 1 second.

I have created an index with all the fields in the WHERE/ORDER BY-part of the query in the same order as they appear in the Query (field1, field2, field3, field4, field5) but it is not used according to "explain" in MySQL.

field1 has rather high cardinality (integer with about 100 different values) field2 and field3 are BOOLEAN and field5 is a string with high cardinality (but LENGTH(field5) > 0 makes the cardinality low, or?).

There is also an index on field5 alone and that is the only index being used when the query looks like above, removing the ORDER BY part of the query will make MySQL use the multi-column index instead.

What am I missing here?

EDIT: here is the actual SQL:

SELECT t.shopid, t.isproduct, t.level, t.isduplicate, t.ref_id 

FROM urls as t

WHERE t.shopid = 72 AND t.isproduct = 1 AND t.visited = 0 AND LENGTH(t.url) > 0  

ORDER BY t.level desc

LIMIT 0, 100;

Its very hard to predict a query performance without actually knowing the table size and data types. Mysql optimizer has it's own ways of deciding which index to use, which in general is pretty good. You can do hit and trial by forcing mysql to use various indexes using FORCE INDEX . Index on t.url can never be used for obvious reasons.

One thing that you can try is this:

select t.field1, t.field2, t.field5, t.field6, t.field7 from (SELECT t.field1, t.field2, t.field5, t.field6, t.field7 FROM mytable as t WHERE t.field1 = a AND t.field2 = b AND t.field3 = c AND LENGTH(t.field4) > 0) t order by t.field5 desc LIMIT 0, 100;

This is generally not recommended but can help you if the output row count is not huge.

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