Почему добавление пятого аргумента в предложении «IN» в MySQL значительно замедляет процесс? - PullRequest
1 голос
/ 01 августа 2009

У меня есть три таблицы с именами Item, Event и Seat, сконструированные так:

Пункт
Id (int)
EventId (int)
Раздел (int)

Событие
Id (int)
VenueId (int)
Конфигурация (int)
HOME_TEAM (INT)

сиденье
Id (int)
VenueId (int)
Конфигурация (int)
Раздел (int)

Я использую следующий запрос, чтобы выбрать все элементы, которые привязаны к определенным домашним командам:

SELECT Item.Id
FROM Item
JOIN Event     
ON Event.Id = Item.EventId    
JOIN Seat USING (VenueId, Configuration)    
WHERE Seat.Section = Item.Section    
AND Event.Home_team IN (1,2,3,4)

Этот запрос выполняется очень быстро - для справки, примерно за 0,6 с. Тем не менее, когда я добавлю дополнительный аргумент к предложению IN в последней строке:

AND Event.Home_team IN (1,2,3,4,5)

... ДРАМАТИЧЕСКИ становится медленнее - для справки, это занимает около 24 секунд.

Я попытался изменить различные аргументы в предложении IN, и не имеет значения, что они; все идет быстро, до четырех, но как только я добавляю пятую, становится намного медленнее. поле Event.Home_team проиндексировано. Я также попытался заменить последнюю строку этой формой:

AND (Event.Home_team = 1 OR Event.Home_team = 2 OR Event.Home_team = 3 OR Event.Home_team =4 OR Event.Home_team =5)

и я нахожу, что для этого также все происходит быстро, когда есть четыре варианта, но очень медленно, когда я добавляю пятый.

Это похоже на странное поведение. Может кто-нибудь сказать мне, почему это происходит?

EDIT
Комментаторы попросили мое объяснение. Вот оно:

**id  select_type  table      type    possible_keys                                  keys        key_len   ref           rows     Extra**
  1   SIMPLE       seat       ref     seat_FI_1,seat_FI_2,section..                  exclude     4         const         17147
  1   SIMPLE       event      ref     PRIMARY,home_team,configuration_id, VenueId    VenueId     5         seat.VenueId  1        Using where
  1   SIMPLE       item       ref     FI_2,item_FI_3                                 FI_2        5         event.id      12       Using where

Кроме того, я должен отметить, что в операторе WHERE есть дополнительное предложение, которое я изначально упустил для простоты:

Seat.exclude = 0

Исключить можно установить на 0 или 1. Он также индексируется.

Ответы [ 2 ]

1 голос
/ 01 августа 2009

Возможно, это пятое значение заставляет MySQL извлекать намного больше строк (если ваше распределение данных сильно смещено в сторону этого Home_team.) Или, возможно, это всего лишь несколько записей, но для MySQL достаточно просто принять решение использовать другой план запроса, и этот другой план запроса может быть неэффективным.

Прежде всего, запустите ANALYZE TABLE (или OPTIMIZE TABLE) для всех задействованных таблиц, если ваша статистика индекса неверна. Затем сравните ОБЪЯСНЕНИЕ обоих запросов, быстрого и медленного.

1 голос
/ 01 августа 2009

Попробуйте соединить идентификатор места с таблицей предметов по SectionID и использовать предложения WHERE для места и конфигурации.

SELECT Item.Id
FROM Item
JOIN Event     
ON Event.Id = Item.EventId    
JOIN Seat 
ON Seat.Section = Item.Section   
WHERE Event.Configuration = Seat.Configuration
AND Event.Venue = Seat.Venue  
AND Event.Home_team IN (1,2,3,4,5)

Убедитесь, что у вас есть индексы для всех Идентификаторов событий и полей Раздела. Индексы в полях Section, Configuration и Home_team также не повредят.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...