MySQL Join занимает слишком много времени - PullRequest
1 голос
/ 16 ноября 2010

Мне нужна помощь в оптимизации запроса или таблицы MySQL

Когда я запускаю этот запрос, он возвращает в 0,01 с 650 записями:

  select mm, name, display, year
  from tbl d
  where active = 1 and tbl2_id = 'val' and lvl_id = 9
  order by mm;

Когда я запускаю этот запрос, он возвращается вболее 15 с с одинаковыми записями:

  select d.mm, d.name, d.display, d.year, a.year year2
  from tbl d left join tbl a on d.mm = a.mm and a.tbl2_id = 'val2'
  where d.active = 1 and d.tbl2_id = 'val' and d.lvl_id = 9
  order by d.mm;

Когда я запускаю его таким образом, это также занимает более 15 с:

  select mm, name, display, year, 
      (select a.year from tbl a where a.mm = mm and a.tbl2_id = 'val2') year2
  from tbl 
  where active = 1 and tbl2_id = 'val' and lvl_id = 9
  order by mm;

таблица содержит несколько записей для мм.Мне нужно получить все записи, где tbl2_id = 'val' и, если есть запись для этого мм, где tbl2_id = 'val2', мне нужно значение "year" из записи val2.В настоящее время в tbl содержится 13 тыс. записей, и для каждого заданного мм не более 10 записей, поэтому я не думаю, что этот запрос должен занимать более 15 с.У меня есть индексы mm, active, tbl2_id и lvl_id.

Я делал подобные вещи в MSSQL практически без задержки.

Ответы [ 3 ]

3 голосов
/ 16 ноября 2010

Вы можете начать с введения составных индексов в свою таблицу на (tbl2_id, lvl_id, active) и (tbl2_id, mm).Это, вероятно, ускорит все три ваших запроса.

Всякий раз, когда вы используете несколько полей в предложении WHERE, имеет смысл рассмотреть составной индекс.Если присутствуют только индексы из одного столбца, запрос может использовать только один из этих индексов для поиска , в то время как приходится искать более медленное сканирование для поиска оставшегося подмножества.Разница между MySQL и MSSQL в этом отношении может заключаться в том, что MSSQL лучше угадывает, какую из этих трех использовать, исходя из мощности ваших данных (лучше всего использовать ту, которая оставляет наименьшее подмножество для сканирования),хотя это трудно сказать, не изучив подробно два плана запросов.

2 голосов
/ 16 ноября 2010

Можете ли вы предоставить DESCRIBE таблиц и EXPLAIN запроса?

Существует известная проблема с использованием строк для поиска INT полей или целых чисел для поиска CHAR /VARCHAR полей.В основном INDEX игнорируется.

Если lvl_id или active равны CHAR / VARCHAR, это может быть причиной.То же самое справедливо для tbl2_id, если это тип INT.

РЕДАКТИРОВАТЬ

Я должен сказать, что 13k записей это ничто, что могло бы объяснить производительность.Однако вы должны учитывать мощность ваших индексов.Если количество элементов составляет менее 30% (среди прочих факторов), ваш индекс не будет использоваться.

Это должно быть понятно при использовании EXPLAIN, чтобы спросить, как оптимизатор запросов выполняет запрос и какие индексы он использует,В некоторых случаях вы можете использовать синтаксис FORCE INDEX , чтобы явно использовать один или несколько индексов.

Также имейте в виду, что добавление составных индексов поможет увеличить скорость запросов (за счет увеличениякардинальность индекса и, следовательно, заставить оптимизатор запросов использовать его автоматически), он также будет иметь обратную сторону.Чем больше индексов, тем больше используется пространства и снижена скорость на UPDATE / INSERT, поскольку нужно обновлять больше вещей.Это особенно актуально, если ваши таблицы становятся довольно большими (в масштабе миллионов строк).

1 голос
/ 16 ноября 2010

Индексирование столбцов, используемых в условии соединения (мм), должно помочь.

...