Что оптимально? СОЮЗ против ГДЕ (стр1, стр2, стр3) - PullRequest
6 голосов
/ 24 августа 2008

Я пишу программу, которая отправляет электронное письмо по местному времени клиента. У меня есть метод .NET, который берет часовой пояс и время и часовой пояс места назначения и возвращает время в этом часовом поясе. Таким образом, мой метод состоит в том, чтобы выбрать каждый отдельный часовой пояс в базе данных, проверить, является ли это правильное время, используя метод, а затем выбрать каждого клиента из базы данных с этим часовым поясом.

Запрос будет выглядеть как один из них. Имейте в виду, что порядок набора результатов не имеет значения, так что объединение будет в порядке. Кто работает быстрее, или они действительно делают то же самое?

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)

или

SELECT email FROM tClient WHERE timezoneID = 1
    UNION ALL SELECT email FROM tClient WHERE timezoneID = 4
    UNION ALL SELECT email FROM tCLIENT WHERE timezoneID = 9

Редактировать: timezoneID - это внешний ключ для tTimezone, таблицы с первичным ключом timezoneID и поля типа timezoneName varchar (20). Кроме того, я пошел с WHERE IN, так как мне не хотелось открывать анализатор.

Редактировать 2: Запрос обрабатывает 200 тыс. Строк менее чем за 100 мс, поэтому на этом я закончил.

Ответы [ 7 ]

3 голосов
/ 24 августа 2008

Эй! Эти запросы не эквивалентны.

Результаты будут такими же, только если предположить, что одно электронное письмо принадлежит только одному часовому поясу. Конечно, он, однако, движок SQL этого не знает и пытается удалить дубликаты. Поэтому первый запрос должен быть быстрее.

Всегда используйте UNION ALL, если вы не знаете, почему хотите использовать UNION.

Если вы не уверены, в чем разница, см. этот ТАК вопрос.

Примечание: этот вопль принадлежит предыдущей версии вопроса.

2 голосов
/ 24 августа 2008

Для большинства вопросов производительности, связанных с базой данных, реальный ответ - запустить его и проанализировать, что БД делает для вашего набора данных. Запустите план объяснения или трассировку, чтобы увидеть, соответствует ли ваш запрос нужным индексам, или, если необходимо, создайте индексы.

Я бы, вероятно, согласился с первым, используя предложение IN, так как оно несет в себе большую семантику того, что вы хотите. TimezoneID выглядит как первичный ключ в некоторой таблице часовых поясов, поэтому он должен быть внешним ключом в электронной почте и индексироваться. В зависимости от оптимизатора БД, я думаю, он должен выполнить сканирование индекса по индексу внешнего ключа.

1 голос
/ 24 августа 2008

В книге «Настройка производительности SQL» авторы обнаружили, что запросы UNION были медленнее во всех 7 протестированных СУБД (SQL Server 2000, Sybase ASE 12.5, Oracle 9i, DB2 и т. Д.): http://books.google.com/books?id=3H9CC54qYeEC&pg=PA32&vq=UNION&dq=sql+performance+tuning&source=gbs_search_s&sig=ACfU3U18uYZWYVHxr2I3uUj8kmPz9RpmiA#PPA33,M1

Более поздние СУБД могли бы оптимизировать эту разницу, но это сомнительно. Кроме того, метод UNION намного длиннее и его сложнее поддерживать (что, если вам нужен третий?) По сравнению с IN.

Если у вас нет веских причин использовать UNION, придерживайтесь метода ИЛИ / В.

1 голос
/ 24 августа 2008

Я думаю, что в этом вопросе отсутствует несколько очень важных сведений. Прежде всего, это очень важно, индексируется ли timezoneID или нет, является ли он частью первичного ключа и т. Д. Я бы посоветовал всем взглянуть на анализатор, но по моему опыту предложение WHERE должно быть быстрее, особенно с индекс. Логика примерно такая: в запросе объединения есть дополнительные издержки, проверка типов, номеров столбцов в каждом и т. Д.

1 голос
/ 24 августа 2008

У меня нет под рукой MS SQL Query Analyzer для проверки моей гипотезы, но я думаю, что вариант WHERE IN будет быстрее, потому что с сервером UNION нужно будет выполнить 3 сканирования таблицы, тогда как с WHERE IN потребуется только один. Если у вас есть Query Analyzer, проверьте планы выполнения для обоих запросов.

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

1 голос
/ 24 августа 2008

Моим первым предположением будет то, что

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
будет быстрее, так как для поиска результатов требуется только одно сканирование таблицы, но я предлагаю проверить план выполнения для обоих запросов.
0 голосов
/ 24 августа 2008

Некоторые оптимизаторы запросов СУБД модифицируют ваш запрос, чтобы сделать его более эффективным, поэтому, в зависимости от используемой СУБД, вам, возможно, это не важно.

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