我必须优化其他人编写的查询,并且我正在努力工作。它有时需要超过12秒才能完成!如何优化带有多个连接和子查询的慢查询
我有一个SQL小提琴here,但是在那里那里有没有数据。我认为数据量部分是缓慢的原因(wed_supplies + postcodes中的20k,注释中的60k)以及num_reviews
和avg_rating
子查询。取出子查询将其取消为2秒钟,但我需要它们提供的值,并且它还需要更快。
SELECT *, c_title AS category,
(SELECT COUNT(*) FROM comments WHERE site_id = '96' AND ec_type = 'review' AND ec_link_id = ws_id) AS num_reviews,
(SELECT AVG(ec_rating) FROM comments WHERE site_id = '96' AND ec_type = 'review' AND ec_link_id = ws_id) AS avg_rating,
(((acos(sin((52.1528253 *pi()/180)) * sin((`p_lat`*pi()/180))
+cos((52.1528253 *pi()/180)) * cos((`p_lat`*pi()/180))
* cos(((-0.6800496 - `p_lng`)*pi()/180))))*180/pi())*60*1.1515)
AS distance
FROM wed_suppliers
LEFT JOIN postcodes ON p_postcode = REPLACE(ws_postcode, ' ', '')
LEFT JOIN c_content ON ws_category = c_id
WHERE wed_suppliers.site_id = '96' AND c_content.site_id = '96'
AND ws_hide = '0'
AND ws_permalink != ''
AND p_lat != '' AND p_lng != '' AND p_invalid = '0'
HAVING distance <= 10
ORDER BY distance ASC
LIMIT 0,20
EXPLAIN
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY wed_suppliers range ws_permalink,site_id,ws_category,ws_hide site_id 4 NULL 22628 Using where; Using temporary; Using filesort
1 PRIMARY postcodes eq_ref PRIMARY,p_invalid,p_lng,p_lat PRIMARY 12 func 1 Using where
1 PRIMARY c_content eq_ref PRIMARY,site_id PRIMARY 4 engine_4.wed_suppliers.ws_category 1 Using where
3 DEPENDENT SUBQUERY comments index_merge site_id,ec_link_id,ec_type site_id,ec_type 4,34 NULL 1 Using intersect(site_id,ec_type); Using where
2 DEPENDENT SUBQUERY comments index_merge site_id,ec_link_id,ec_type site_id,ec_type 4,34 NULL 1 Using intersect(site_id,ec_type); Using where
我已经使用的EXPLAIN返回什么this glossary,但没有多少运气。
如何优化此查询以便以更合理的速度运行?我如何将EXPLAIN翻译成更有用的东西。
如果你可以修改数据库模式,你可以查看你的索引 – heringer
@heringer索引是在sqlfiddle链接我发布在顶部 – Horse
@Horse - 表不是很大。你可以尝试1:在运行查询之前清理数据,从而避免在连接中使用REPLACE函数? 2.为子查询创建临时表,然后将其与主查询结合起来? – Shiva