0

表中 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
4

1 回答 1

1

我将反转查询并首先从状态开始,因为这是您的标准所依据的。由于您实际上并没有对国家/地区表做任何事情(国家/地区 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
于 2013-05-20T19:17:04.220 回答