Как оптимизировать этот запрос на соединение? - PullRequest
0 голосов
/ 05 августа 2011

Вот мой предыдущий опыт оптимизации SQL-соединения:

в MySQL, чтобы иметь быстрое соединение, обычно я избегаю типа «Все». По сути, объединение будет быстрее, если в таблице есть индексные поля. Даже если вы используете предложение WHERE и т. Д. Для создания меньших подмножеств, если два подмножества не имеют индекса для объединения, этот запрос должен быть намного медленнее, чем полное объединение таблиц с индексами, а затем применять предложение WHERE и т. Д., Чтобы получить окончательный набор результатов. .

Однако, как оптимизировать такого рода запросы?

Я должен выбрать подмножества для объединения. В этом случае эти производные подмножества не будут иметь индекс для объединения.

Вот конкретная проблема, с которой я столкнулся:

У меня есть таблица с именем Contract, и в ней есть следующие поля (для простоты, фактически больше полей):

SN, type, date, flag

SN и тип являются его первичным ключом, поле флага может быть 0/1/2

Вот запрос на соединение, который я создал:

SELECT f0_crt.SN, f0_crt.f0_Info, f1_Info
FROM 
  (SELECT a.SN, GROUP_CONCAT(a.type, '-', a.date SEPARATOR '*') as f0_Info
   FROM Contract a
   WHERE a.flag=0 
   GROUP BY SN
   ORDER BY SN ) AS f0_crt
  LEFT JOIN 
  (SELECT b.SN, GROUP_CONCAT(b.type, '-', b.date SEPARATOR '*') as f1_Info
    FROM Contract b
    WHERE b.flag=1 
    GROUP BY SN
    ORDER BY SN ) AS f1_crt
    ON f0_crt.SN=f1_crt.SN

В основном мне нужно, чтобы набор результатов был таким:

SN                  f0_Info                              f1_Info
abc        COMB-20100911*CDMA-20090701        FFIV-20100911*SPRT-20090701

Вот результат EXPLAIN:

id  select_type   table     type    possible_keys   key key_len ref rows    Extra
---------------------------------------------------------------------------------------------
1   PRIMARY      derived2    ALL           (NULL)    (NULL) (NULL)    (NULL)    15052    
1   PRIMARY      derived3    ALL           (NULL)    (NULL) (NULL)    (NULL)    29407    
3   DERIVED         b      index    seq_num_index   PRIMARY    184  (NULL)  81982    
2   DERIVED         a       index   seq_num_index   PRIMARY    184  (NULL)  81982    

это на самом деле ОБЪЯСНЕННЫЙ результат, ключевая причина медлительности, которую я думаю: два объединения ВСЕ. Тем не менее, я не знаю, как избежать этого здесь? Есть ли способ получить нужный мне формат группы, а затем выполнить соединение с SN, чтобы можно было использовать индекс SN и т. Д.?

Спасибо!

1 Ответ

0 голосов
/ 05 августа 2011

Что если вы измените свой запрос, чтобы он выглядел примерно так?

SELECT a.SN, GROUP_CONCAT(a.type, '-', a.date SEPARATOR '*') as f0_Info,
       GROUP_CONCAT(b.type, '-', b.date SEPARATOR '*') as f1_Info
  FROM Contract a
  LEFT JOIN Contract b
      on a.SN = b.SN and b.flag = 1
  WHERE a.flag=0 
  GROUP BY a.SN
  ORDER BY a.SN 
...