I don't use MySQL very often (happy PostgreSQL user), but I had occasion to use it for a client recently. A proxy server spits out log entries into a very large database table, which is then queried through a web interface. The table has an index for the date/time, and an index for a text field explaining what the proxy did. It won't permit the generation of an index for both, since that exceeds the key-size limit.
The following query runs great, and properly uses the datetime index (the limit is because it's used for a dashboard display):
SELECT * FROM log ORDER BY datetime DESC LIMIT 50;
This query runs great, too:
SELECT * FROM log WHERE what LIKE '*DENIED*%' LIMIT 50;
In both cases, the optimizer correctly picks the index - and the query runs really fast. However, when one attempts to combine the two, life is not so great:
SELECT * FROM log WHERE what LIKE '*DENIED*%' ORDER BY datetime DESC LIMIT 50;
The query takes a really, really long time to run! EXPLAINing the query shows that it uses the index correctly for "what", but then performs a filesort for the date sort! Since adding a large amount of very-high-performance temporary file storage isn't an option here, there's a problem. Digging into the MySQL documentation, it turns out that MySQL can't perform an ORDER BY using an index if a WHERE clause uses a different index! It was actually several thousand times faster to read the results into PHP sorted and perform the string comparison there. Gahh!
Subscribe to:
Post Comments (Atom)

No comments:
Post a Comment