Вопрос

Я пишу программу, которая отправляет электронное письмо в определенное местное время клиента.У меня есть метод .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 и полем varchar(20) timezoneName. Кроме того, я пошел с WHERE IN так как мне не хотелось открывать анализатор.

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

Мое первое предположение было бы таков

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

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

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

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

В книге «Настройка производительности 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 намного длиннее и его сложнее поддерживать (что, если вам нужен третий?) по сравнению с методом UNION.ИН.

Если у вас нет веской причины использовать UNION, придерживайтесь метода OR/IN.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top