帮我优化这个查询

时间:2011-05-29 12:02:28

标签: mysql optimization

请建议索引以优化以下查询。我不能允许重写查询但是创建索引:

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`)

提前致谢。

2 个答案:

答案 0 :(得分:2)

好吧,也许我不是MySQL优化的专家,但是:

  • 如果可行且合理,尽量避免在可能的情况下进行子选择(相反,最好进行单独查询,然后将检索到的ID(如comp_id)传递给包含的查询),
  • 将索引放在comp.name上,
  • 将索引放在advts_post.comp_id(单一)上,
  • 将索引放在advts_post.ad_id(单一)上,

也许这很简单,但应该至少稍微让它更快。告诉我们结果。

答案 1 :(得分:0)

那个问题是狗的晚餐 - 无论是谁写的都应该受到严厉的惩罚,那个说你不能重写它但必须让它跑得更快的人应该被枪杀。

放松子选择!

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