Почему мой SQL такой медленный? - PullRequest
0 голосов
/ 04 марта 2011

Моя таблица достаточно мала, около 50 000 строк.Моя схема выглядит следующим образом:

DAILY

  • match_id
  • user_id
  • результат
  • раунд
  • tour_id

Запрос:

SELECT user_id 
  FROM `daily` 
 WHERE user_id IN (SELECT user_id 
                     FROM daily 
                    WHERE round > 25 
                      AND tournament_id = 24 
                      AND (result = 'Won' OR result = 'Lost'))

Ответы [ 4 ]

3 голосов
/ 04 марта 2011

Использование ключевого слова in таким способом, которым вы являетесь, является очень опасным [с точки зрения производительности]. Это приведет к тому, что в этом случае подзапрос [(выберите user_id из ежедневного, где раунд> 25 и tour_id = 24 и (result = 'Won' или result = 'Lost'))] будет выполнен 50 000 раз.

Вы захотите преобразовать это в соединение с эффектом

select user_id from daily a join
       (select user_id from daily where round > 25 and tournament_id=24 and (result='Won' or result='Lost')) b on a.user_id = b.user_id

Выполнение чего-либо подобного приведет к двум запросам и объединению.

Как указал Cybernate в своем конкретном примере, вы можете просто использовать предложения where, но я предложил это в случае, если ваш запрос на самом деле более сложный, чем тот, который вы опубликовали.

2 голосов
/ 04 марта 2011

Сначала проверьте и добавьте индексы, как предлагалось ранее.

Также, почему вы используете in, если запрашиваете данные из той же таблицы. Измените ваш запрос на:

SELECT user_id 
FROM   daily 
WHERE  round > 25 
       AND tournament_id = 24 
       AND ( result = 'Won' 
              OR result = 'Lost' ) 
1 голос
/ 04 марта 2011

Ваш запрос должен быть только:

SELECT d.user_id 
  FROM DAILY d
 WHERE d.round > 25 
   AND d.tournament_id = 24 
   AND d.result IN ('Won', 'Lost')

Индексы должны учитываться на:

  • DAILY.round
  • DAILY.tournament_id
  • DAILY.result
0 голосов
/ 04 марта 2011

Возвращается через миллисекунду.

SELECT user_id FROM daily WITH(NOLOCK) 
where user_id in (select user_id from daily WITH(NOLOCK)  where round > 25 and tournament_id = 24 and (result = 'Won' or result = 'Lost'))

Затем убедитесь, что в столбцах фильтра есть индекс.

CREATE NONCLUSTERED INDEX IX_1 ON daily (round ASC, tournament_id ASC, result ASC)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...