2013-05-20 219 views
0

MySQL查询服用1.6秒40000个记录表优化与查询索引

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的记录.... 500records在STATEDM ABD 4个记录COUNTRY表。 当我上面的查询运行它正在1.6 sec..Is有没有办法优化查询或索引上的列将提高性能.... 以下是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

我会反向查询并首先从STATE开始,因为这是您的标准所依据的。由于您实际上没有对国家/地区表执行任何操作(国家/地区ID除外)......此列也存在于州表中,因此您可以使用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 
+0

Thanks DRapp。对我来说很好的学习......但是我有疑问....当我在上面的查询上运行EXPLAIN时.... ....我正在使用temporary,filesort ...我们怎样才能摆脱那... – Sarath

+0

@Sarath,你是否只有一个索引(Country_ID),或者至少country_id在第一位?我发现最接近匹配查询条件的列的顺序有助于更高效地进行优化。 – DRapp

+0

我有与第一位置COUNTRY_ID索引.. 1个\t \t SIMPLE statedm \t \t索引PRIMARY,state_id_UNIQUE,state_country_fk_idx,country_idx \t \t state_country_fk_idx 8 \t \t \t 69使用其中;使用索引;使用临时;使用filesort – Sarath