问题描述
|
请提出索引以优化下面的查询。我不允许重写查询,但可以创建索引:
SELECT
`ADV`.`inds` as `c0`,sum(`ADVpost`.`clk`) as `m0`
FROM
(SELECT *
FROM advts
WHERE comp_id =
(SELECT comp_id
FROM comp
WHERE name = \'abc\')) as `ADV`,(SELECT dt_id,comp_id,b_id,ad_id,clk,resp
FROM advts_post
WHERE comp_id =
(SELECT comp_id
FROM comp
WHERE name = \'abc\')) as `ADVpost`
WHERE
`ADVpost`.`ad_id` = `ADV`.`ad_id`
GROUP BY
`ADV`.`inds`
ORDER BY
ISNULL(`ADV`.`inds`),`ADV`.`inds` ASC
该查询的说明如下:
select_type table type possible_keys Extra
PRIMARY <derived2> ALL null Using temporary; Using filesort
PRIMARY <derived4> ALL null Using where; Using join buffer
DERIVED ADVpost ALL null Using where
SUBQUERY comp ALL null Using where
DERIVED advts ALL null Using where
SUBQUERY comp ALL null Using where
现有索引如下:
ADVpost > PRIMARY KEY (`dt_id`,`comp_id`,`b_id`,`ad_id`)
comp > PRIMARY KEY (`comp_id`)
advts > PRIMARY KEY (`ad_id`)
提前致谢。
解决方法
该查询是一场狗狗大餐-写下该查询的人都应受到严惩,说您不能重写但必须使其运行得更快的人应该被枪杀。
松开子选择!
MySQL的推式谓词做得不是很好(完全吗?)。
请使用适当的联接,并声明隐式联接:
SELECT ap.inds,SUM(ap.clk)
FROM advts_post AS ap,comp AS co,advts ad
WHERE ap.comp_id = co.comp_id
AND ad.comp_id = co.comp_id
AND ap.comp_id = ad.comp_id
AND co.name=\'abc\'
GROUP BY ap.inds
ORDER BY ISNULL(ap.inds),ap.inds ASC
, 好的,也许我不是MySQL优化专家,但是:
如果可能且合理,请尝试避免在可能的情况下进行子选择(相反,最好进行单独的查询,然后将检索到的ID(例如“ 4”)传递给包含的查询),
将索引放在comp.name
上,
将索引放在advts_post.comp_id
(单数)上,
将索引放在advts_post.ad_id
(单数)上,
也许它很简单,但至少应该有助于使其更快。告诉我们结果。