2013-05-27 2 views
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 

раскомментирован заказ по п заставит aggsm таблицы использовать «используя временный, используя FileSort»

Как мы можем оптимизировать запрос или определить индекс

+0

Некоторые идеи ... Не знаю, улучшатся ли они - просто попытаться помочь хотя :) 1) если возможно разделить этот массивный запрос (для пример с php) на более мелкие части. 2) попытайтесь уменьшить результат в резервной памяти; название темы может сделать ее довольно большой или рассмотреть подкачку результата 3) проверить вашу конфигурацию mysql и повысить лимиты в зависимости от используемого вами двигателя – viljun

+0

1.1 кажется мне очень хорошим :-(. Тем не менее, у вас есть указатель, определяемый через (cdm_id , ei_type, datedm_id)? – Strawberry

ответ

0

1) LIMIT 0,200000 определенно не очень хорошее решение, я едва вижу приложение, в котором вам нужен такой большой объем данных, разделить его на куски

2) в ORDER BY предложении, вы указываете и сумма (aggsm.m_count) - это агрегатная функция, попробуйте решение как mencnt (поэтому ORDER BY DESC aggsm.topicdm_id, mencnt DESC), не уверен, SQL-сервер понимает это так, как вы хотите.

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 
Смежные вопросы