我在优化非常慢的SQL查询时遇到问题。我认为是一个索引问题,但我找不到我必须应用的索引。
这是查询:
SELECT
cl.ID, cl.title, cl.text, cl.price, cl.URL, cl.ID AS ad_id, cl.cat_id,
pix.file_name, area.area_name, qn.quarter_name
FROM classifieds cl
/*FORCE INDEX (date_created) */
INNER JOIN classifieds_pix pix ON cl.ID = pix.classified_id AND pix.picture_no = 0
INNER JOIN zip_codes zip ON cl.zip_id = zip.zip_id AND zip.area_id = 132
INNER JOIN area_names area ON zip.area_id = area.id
LEFT JOIN quarter_names qn ON zip.quarter_id = qn.id
WHERE
cl.confirmed = 1
AND cl.country = 'DE'
AND cl.date_created <= NOW() - INTERVAL 1 DAY
ORDER BY
cl.date_created
desc LIMIT 7
MySQL需要大约2秒才能获得结果,并开始使用pix.picture_no,但如果我强制索引为“date_created”,则查询速度会快得多,并且只需0.030秒。但问题是“INNER JOIN zip_codes ...”并不总是在查询中,如果不是,强制索引会使查询再次变慢。
我一直在考虑通过PHP条件制定解决方案,但我想知道索引的问题是什么。
答案 0 :(得分:0)
在查询前添加explain
并再次运行
这将显示正在使用的索引。
请参阅:http://dev.mysql.com/doc/refman/5.0/en/explain.html
有关explain
的解释,请参阅:http://www.slideshare.net/phpcodemonkey/mysql-explain-explained
或者:http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm
答案 1 :(得分:0)
我实际上会在你所在的所有元素上有一个复合索引,例如
(国家,已确认,date_created)
让国家优先将优化的索引子集首先保留在一个国家/地区,然后在其中,确认,最后是日期范围本身。不要仅仅查询日期索引。由于您按日期排序,因此索引也应该能够对其进行优化。
答案 2 :(得分:0)
以下是有关如何优化查询的几点建议。
我使用EverSQL SQL Query Optimizer来获取这些建议(免责声明:我是EverSQL的联合创始人,并谦虚地提供这些建议)。