Это простой вопрос, на который я не могу найти ответ.
С точки зрения производительности, если у меня есть такое WHERE
условие a=0 and b=0 and ... z=0
, могу ли я получить какую-либо производительность, если я заменю это условие на a+b+...+z=0
?
Другими словами, есть ли прирост производительности путем замены следующего
Select *
From MyTable
Where A=0 and B=0 and C=0 and D=0...
С
Select *
From MyTable
Where A+B+C+D=0...
Я знаю, что это может зависеть от индексов, но для этого, скажем так, индексов не существует. Работает ли арифметический оператор (+) лучше, чем логический оператор «ИЛИ» или «И»?
У меня сложилось впечатление, что сложение выполняется лучше, чем несколько условий с AND или OR.
Результаты теста
На таблице 4,2 миллиона строк
Возвращаемые строки, где A = 0, B = 0 и C = 0 -> 351748 строк
Добавление (A + B + C = 0) заняло 5 секунд, в то время как логические условия A = 0 и B = 0 и C = 0 заняли 11 секунд.
С другой стороны
Возвращение строк, где A <> 0 B <> 0 или C <> 0 -> 3829750 Строки 58 секунд
Возврат строк, где F65 + F67 + f64 <> 0 -> 3829750 Строки 57 секунд
Для OR, кажется, нет существенной разницы.
Я согласен с ГБН:
Если A равно -1, а B равно 1, A + B = 0, но A = 0 и B = 0 ложно
и с AMtwo:
ABS (A) + ABS (B) + ABS (C) + ABS (D) ... Даже если вы ожидаете только положительные значения, если столбец принимает отрицательные значения, вы должны предположить, что вы можете столкнуться с одним
Результаты очень впечатляющие, как я и думал, кажется, что сложение происходит намного быстрее, чем у логических операторов.
A = плавать, B = деньги и C = плавать. Используемый запрос как показано. В моем случае все положительные числа. Нет индексов. Просто логично, что сложение будет быстрее, чем логические условия!
Ответы:
В своем вопросе вы детализируете подготовленные вами тесты, в которых вы «доказываете», что опция добавления выполняется быстрее, чем сравнение отдельных столбцов. Я подозреваю, что ваша методология тестирования может быть ошибочной по нескольким причинам, на что ссылались @gbn и @srutzky.
Во-первых, вам нужно убедиться, что вы не тестируете SQL Server Management Studio (или любой другой клиент, который вы используете). Например, если вы запускаете
SELECT *
из таблицы с 3 миллионами строк, вы в основном тестируете способность SSMS извлекать строки из SQL Server и отображать их на экране. Вам гораздо лучше использовать что-то подобное,SELECT COUNT(1)
что устраняет необходимость протягивать миллионы строк по сети и отображать их на экране.Во-вторых, вам нужно знать о кеше данных SQL Server. Как правило, мы тестируем скорость чтения данных из хранилища и обработки этих данных из холодного кэша (т. Е. Буферы SQL Server пусты). Время от времени имеет смысл проводить все тестирование с использованием «теплого кэша», но вам необходимо явно подходить к тестированию с учетом этого.
Для теста с холодным кэшем необходимо запускать
CHECKPOINT
иDBCC DROPCLEANBUFFERS
перед каждым запуском теста.Для теста, который вы задали в своем вопросе, я создал следующий тестовый стенд:
Это возвращает подсчет 260 144 641 на моей машине.
Чтобы проверить метод «сложения», я запускаю:
Вкладка сообщений показывает:
Для теста "дискретные столбцы":
снова с вкладки сообщений:
Из приведенной выше статистики вы можете видеть второй вариант, когда дискретные столбцы сравниваются с 0, истекшее время примерно на 10 секунд короче, а время процессора примерно в 6 раз меньше. Большая длительность моих тестов выше, в основном, является результатом чтения большого количества строк с диска. Если вы уменьшите число строк до 3 миллионов, вы увидите, что отношения остаются примерно такими же, но затраченное время заметно падает, поскольку дисковый ввод-вывод оказывает гораздо меньшее влияние.
С помощью метода «Дополнение»:
С помощью метода «дискретные столбцы»:
Что будет действительно очень важно для этого теста? Соответствующий индекс, такой как:
Метод «сложения»:
Метод «дискретных столбцов»:
План выполнения для каждого запроса (с указанным индексом на месте) довольно показателен.
Метод сложения, который должен выполнить сканирование всего индекса:
и метод «дискретных столбцов», который может искать первую строку индекса, где находится ведущий столбец индекса
A
, равен нулю:источник
Допустим, у вас есть индекс на A, B, C и D. Также можно отфильтровать.
Это более вероятно использовать индекс, чем сложение.
В других новостях, если A равно -1, а B равно 1,
A+B=0
верно, ноA=0 and B=0
неверно.источник
(Обратите внимание, что этот ответ был представлен до того, как какое-либо тестирование было отмечено в Вопросе: текст Вопроса заканчивался чуть выше раздела с результатами теста .)
Я бы предположил, что отдельные
AND
условия предпочтительнее, поскольку оптимизатор с большей вероятностью закорачивает операцию, если одно из них не равно 0, без необходимости сначала выполнять вычисления.Тем не менее, поскольку это вопрос производительности, вам следует сначала установить тест, чтобы определить ответ на вашем оборудовании. Сообщите об этих результатах, указав свой тестовый код, и попросите других просмотреть его, чтобы убедиться, что это хороший тест. Могут быть и другие факторы, заслуживающие рассмотрения, о которых вы не задумывались.
источник
Некоторые общие соображения: если у вас нет под рукой никаких индексов, я не думаю, что это будет иметь большое значение, какое из двух решений вы выберете, оба будут работать плохо. С другой стороны, если у вас есть индекс по одному или нескольким столбцам в предикате, первый из них, вероятно, будет работать лучше, чем второй, поскольку второй, вероятно, не сможет использовать индекс (ы).
В целом дизъюнкция (OR) работает хуже, чем конъюнкция (AND), но даже если у вас есть запрос с дизъюнкциями, я положу свои деньги на первый.
источник
Нет это не так. Этот (своего рода) вопрос - то, что изводит многих администраторов баз данных и разработчиков программного обеспечения изо дня в день, и это почти тривиально.
Да не будешь По крайней мере, не общий ответ. Прежде всего, это будет сильно зависеть от того, какую СУБД вы используете (хорошо, вы используете sql-сервер , но все же). Это может даже измениться, когда вы переходите от одной версии вашей RDBMS к другой.
Затем это может зависеть от любого количества других мелких деталей, например, как ваша БД хранит данные, если у вас есть подвыборы / объединения, которые путают проблему с оптимизатором плана и т. Д. Оптимизатор может предоставить вам разные планы выполнения в зависимости от на сколько строк у вас есть ...
Выполнение теста в реальном мире обычно является единственным полезным способом решения подобных вопросов. Кроме того, любые выгоды, получаемые от «тайных» оптимизаций, подобных этой, обычно поглощаются в десять раз благодаря разумному выбору индексов, поэтому я бы не стал тратить на это слишком много времени, прежде чем использование индексов действительно будет исключено.
источник
Это может быть очевидно, но если столбцы равны
INT
, тоa+b+c
могут равняться нулю, даже если ни один из них на самом деле не равен нулю. Вы тестируете две разные вещи!источник