I’m looking to improve the query performance of the following mysql query:
SELECT * FROM items
WHERE items.createdAt > ?
AND items.createdAt + items.duration < ?
What are the best indexes to use here? Should I have one for both (createdAt) and (createdAt, duration)?
Thanks!
2
Answers
Create one index on
createdAt
Then create a generated (aka computed column) column on
createdAt + duration
and then create an index on the generated column.https://dev.mysql.com/doc/refman/8.0/en/create-table-secondary-indexes.html
You can’t easily sove the problem. Indexes are one-dimensional. You need a 2D index.
SPATIAL
provides such, but it would be quite contorted to re-frame your data into such.PARTITION
sort of gives an extra dimension; but, again, I don’t see that as viable.So, but best you can do is
Or perhaps this is a little better:
I don’t see that a "generated" column will solve the problem — however it may lead to sometimes running faster for this simple reason:
createdAt > ?
filters out most of the table becausecreatedAt
is near the end, theINDEX(createdAt)
appears to be a good index.?
is near the beginning of time, such an index is essentially useless– because most of the table needs to be scanned.createdAt + duration
has the same problem, just in the other direction.If the real query has an
ORDER BY
andLIMIT
, there may be other tricks to play. I discuss that when trying to map IP-addresses to countries or businesses: http://mysql.rjweb.org/doc.php/ipranges