0

以下は、1.1 秒かかる集計クエリです。このクエリには複数の結合があります。クエリを最適化する列のインデックス。

         EXPLAIN SELECT straight_join
          aggsm.tdm_id AS topid,              
          sum(aggsm.m_count) AS mencnt ,
          sum(aggsm.ps_count) AS pscnt,
          sum(aggsm.ns_count) AS ngscnt,
          topdm.topic_name AS topname
         FROM AGG_MENTION AS aggsm 
         JOIN TOPICDM AS topdm  ON aggsm.topicdm_id = topdm.topicdm_id
         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
         WHERE aggsm.cdm_id = 11
         AND aggsm.ei_type IN (1,2,3,4)
         AND aggsm.datedm_id BETWEEN 20130101 AND 20130522   
         AND statedm.country_id IN (1,2,3,4) 
         AND topdm.topic_group_id IN (1,2,3,4,5,6,7)    
         GROUP BY aggsm.topicdm_id
         -- ORDER BY aggsm.topicdm_id DESC,sum(aggsm.m_count) DESC
         LIMIT 0,200000

以下は説明出力です:

   1    SIMPLE  aggsm   ref PRIMARY,datedm_id_UNIQUE,agg_sm_locdm_fk_idx,agg_sm_comdm_fk_idx,agg_sm_topdm_fk_idx,agg_sm_datedm_fk_idx,agg_em_indtype_fk_idx,comp_top_dt,l_idx   comp_top_dt 8   const   202129  Using where; Using index
   1    SIMPLE  topdm   eq_ref  PRIMARY,topicdm_id_UNIQUE,topdm_grp_id_idx,id_idx   PRIMARY 8   opinionleaders.aggsm.topicdm_id 1   Using where
   1    SIMPLE  locdm   eq_ref  PRIMARY,city_id_UNIQUE,locationdm_id_UNIQUE,loc_city_fk_idx,id_idx  PRIMARY 8   opinionleaders.aggsm.locationdm_id  1   
   1    SIMPLE  citydm  eq_ref  PRIMARY,city_id_UNIQUE,city_state_fk_idx,id_idx PRIMARY 8   opinionleaders.locdm.city_id    1   
   1    SIMPLE  statedm eq_ref  PRIMARY,state_id_UNIQUE,state_country_fk_idx,id_idx PRIMARY 8   opinionleaders.citydm.state_id  1   Using where

order by 句のコメントを外すと、aggsm テーブルで「using temporary,using filesort」が使用されます。

クエリを最適化したり、インデックスを定義したりするにはどうすればよいですか

4

2 に答える 2

0

読みやすくするためにクエリをわずかに再フォーマットし、インデックスの考慮事項として関係と関連する列を表示します。Aggsm テーブルは topicdm_id によってグループ化されているため、少なくともこれと列を使用してカバー インデックスを取得して、結合されたテーブルにアクセスできるようにします。そのため、修飾されたレコードが得られるまで生のページ データにアクセスする必要はありません。で作業します。また、where 句のコンポーネントを含めます。テーブルにインデックスを作成することをお勧めします

table        index
agg_mention  ( cdm_id, ei_type, datedm_id, topicdm_id, locationdm_id )
topicdm      ( topicdm_id, topic_group_id )
state        ( state_id, country_id )
locationdm   ( locationdm_id )
city         ( city_id )

SELECT straight_join
      aggsm.tdm_id AS topid,
      sum(aggsm.m_count) AS mencnt,
      sum(aggsm.ps_count) AS pscnt,
      sum(aggsm.ns_count) AS ngscnt,
      topdm.topic_name AS topname
   FROM 
      AGG_MENTION AS aggsm 
         JOIN TOPICDM AS topdm  
            ON aggsm.topicdm_id = topdm.topicdm_id
            AND topdm.topic_group_id IN (1,2,3,4,5,6,7)    
         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
                  AND statedm.country_id IN (1,2,3,4) 
   WHERE 
          aggsm.cdm_id = 11
      AND aggsm.ei_type IN (1,2,3,4)
      AND aggsm.datedm_id BETWEEN 20130101 AND 20130522   
   GROUP BY 
      aggsm.topicdm_id
   ORDER BY 
      aggsm.topicdm_id DESC,
      sum(aggsm.m_count) DESC
   LIMIT 
      0,200000
于 2014-02-06T14:13:14.587 に答える
0

1)LIMIT 0,200000は間違いなく良い解決策ではありません。このような大量のデータが必要なアプリケーションをほとんど見ることができず、チャンクに分割します

2) ORDER BY 句で、sum(aggsm.m_count) を指定しています。これは集計関数です。mencnt としてアドレス指定してみてください (したがって、ORDER BY aggsm.topicdm_id DESC,mencnt DESC )。SQL サーバーがそれを次のように理解するかどうかはわかりません。あなたが欲しい

于 2014-02-06T13:49:09.430 に答える