使用索引优化查询

时间:2013-05-20 17:37:34

标签: mysql

对于表中的40000条记录,MySQL查询占用1.6秒

 SELECT aggsm.topicdm_id AS topid,citydm.city_name
 FROM AGG_MENTION AS aggsm
 JOIN LOCATIONDM AS locdm ON aggsm.locationdm_id = locdm.locationdm_id
 JOIN CITY AS citydm ON locdm.city_id = citydm.city_id
 JOIN STATE AS statedm ON citydm.state_id = statedm.state_id
 JOIN COUNTRY AS cntrydm ON statedm.country_id = cntrydm.country_id
 WHERE  cntrydm.country_id IN (1,2,3,4)
 GROUP BY aggsm.topicdm_id,aggsm.locationdm_id
 LIMIT 0,200000

我在AGG_MENTION,LOCATIONDM,CITYDM表中有40000到50000条记录....在STATEDM中有500条记录,在COUNTRY表中有4条记录。 当我运行上面的查询它需要1.6秒..有一种方法来优化查询或索引哪些列将提高性能.... 以下是EXPLAIN输出:

   1    SIMPLE  aggsm   index   agg_sm_locdm_fk_idx agg_sm_datedm_fk_idx    4       36313   Using index; Using temporary; Using filesort
   1    SIMPLE  locdm   eq_ref  PRIMARY,city_id_UNIQUE,locationdm_id_UNIQUE,loc_city_fk_idx PRIMARY 8   opinionleaders.aggsm.locationdm_id  1   
   1    SIMPLE  citydm  eq_ref  PRIMARY,city_id_UNIQUE,city_state_fk_idx    PRIMARY 8   opinionleaders.locdm.city_id    1   
   1    SIMPLE  statedm eq_ref  PRIMARY,state_id_UNIQUE,state_country_fk_idx    PRIMARY 8   opinionleaders.citydm.state_id  1   Using where
   1    SIMPLE  cntrydm eq_ref  PRIMARY,country_id_UNIQUE   PRIMARY 8   opinionleaders.statedm.country_id   1   Using index

1 个答案:

答案 0 :(得分:1)

我会反转查询并首先从STATE开始,因为这是您的标准所基于的。由于您实际上没有对国家/地区表执行任何操作(国家/地区ID除外)...此列也存在于State表中,因此您可以使用State.Country_ID并从联接中删除国家/地区表。

另外,我会有以下索引

Table         Index
State         (Country_ID) as that will be basis of your WHERE criteria.  
City          (State_ID, City_Name).  
Location      (City_ID)
Agg_Mention   (LocationDM_ID, TopicDM_id).

通过将“City_Name”作为索引的一部分,查询不必转到它的实际页面数据。由于索引的一部分,它可以直接使用它。

很多时候,此处包含的关键字“STRAIGHT_JOIN”可帮助优化器按所述顺序运行查询,因此它不会尝试将其他表中的一个作为查询数据的主要基础。如果效果不佳,可以在没有它的情况下再次尝试。

SELECT STRAIGHT_JOIN
      aggsm.topicdm_id AS topid,
      citydm.city_name
   FROM 
      STATE AS statedm 
         JOIN CITY AS citydm 
            ON statedm.state_id = citydm.state_id
               JOIN LOCATIONDM AS locdm 
                  ON citydm.city_id = locdm.city_id 
                     join AGG_MENTION AS aggsm
                        ON locdm.locationdm_id = aggsm.locationdm_id 
   WHERE
      statedm.country_id IN (1,2,3,4)
   GROUP BY 
      aggsm.topicdm_id,
      aggsm.locationdm_id
   LIMIT 0,200000