Оператор «<>» SQL Server очень медленный по сравнению с «=» в таблице с несколькими миллионами строк - PullRequest
10 голосов
/ 14 сентября 2011

У меня есть две таблицы. Формы имеет ~ 77000 строк. В журналах ~ 2,7 миллиона строк.

Следующий запрос возвращает «30198» менее чем за секунду:

SELECT COUNT(DISTINCT logs.DOCID) FROM logs, forms WHERE logs.DOCID = forms.DOCID;

И этот запрос выполнялся в течение ~ 15 минут и до сих пор не завершен:

SELECT COUNT(DISTINCT logs.DOCID) FROM logs, forms WHERE logs.DOCID <> forms.DOCID;

Почему запрос "не равен" так намного медленнее?

Ответы [ 3 ]

28 голосов
/ 14 сентября 2011

Поскольку = сокращает операцию объединения до одной подходящей строки из каждой таблицы (при условии, что эти документы уникальны).

Подумайте об этом так: вы танцуете с 5 мальчиками и 5девочки:

Adam      Alice
Bob       Betty
Charly    Cathy
Dick      Deb
Evan      Elly

Вы соединяете их по первой букве.Итак,

Adam->Alice
Bob->Betty
etc...

Одна единичная пара

Но если вы объедините их с помощью "Первые буквы НЕ совпадают", вы получите:

Adam->Betty
Adam->Cathy
Adam->Deb
Adam->Elly
Bob->Alice
etc...

you 'Мы МАССИВНО увеличили количество пар.Вот почему ваш <> запрос занимает так много времени.По сути, вы пытаетесь получить m x n строк, а не просто min(m,n).Получив эти данные, вы получите 25 строк, а не 5. Для указанных размеров таблицы вы работаете с 77 000 * 2 700 000 = 207,9 миллиардов строк, минус 77 000, где совпадают два идентификатора, в общей сложности 207 899 923 000 строк вобъединенный набор данных.


с учетом требований вашего запроса, попробуйте выполнить левое соединение и найдите нулевые правые записи:

SELECT DISTINCT logs.DOCID
FROM logs
LEFT JOIN forms ON logs.DOCID = forms.DOCID
WHERE forms.DOCID IS NULL
2 голосов
/ 14 сентября 2011

Две причины:

  • запросы на эквивалентность могут обычно использовать индексы (если доступны), тогда как запрос на неэквивалентность не может

  • <> возвращает намного больше данных.

Ваш запрос с <> является поддельным. Что он должен вернуть?

1 голос
/ 14 сентября 2011

Это полностью зависит от распределения значений в таблице.Например, если столбец, который вы ищете, имеет одинаковое значение (= forms.DOCID) для 99,99% строк и только одну строку с другим значением, вы увидите совершенно противоположное поведение.

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