Лучше соединить два поля вместе или сравнить их каждое с одной и той же константой? - PullRequest
2 голосов
/ 16 сентября 2008

Например, что лучше:

select * from t1, t2 where t1.country='US' and t2.country=t1.country and t1.id=t2.id

или

select * from t1, t2 where t1.country'US' and t2.country='US' and t1.id=t2.id

лучше, чем меньше работы с базой данных, тем быстрее результаты.

Примечание: Sybase, и для обеих таблиц есть индекс country+id.

Ответы [ 11 ]

3 голосов
/ 16 сентября 2008

Здесь есть много факторов, которые вы упустили. Что это за база данных? Эти таблицы проиндексированы? Как они индексируются? Насколько велики эти таблицы?

(Преждевременная оптимизация - корень всего зла!)

Может случиться так, что если проиндексированы "t1.id" и "t2.id", ядро ​​базы данных объединяет их вместе на основе этих полей и затем использует оставшуюся часть предложения WHERE для фильтрации строк.

Они могут быть проиндексированы, но невероятно маленькими таблицами, и оба помещаются на странице памяти. В этом случае ядро ​​базы данных может просто выполнить полное сканирование обоих, а не загружать индекс.

Ты просто не знаешь, правда, пока не попробуешь.

3 голосов
/ 16 сентября 2008

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

Я лично предпочитаю первую форму:

выберите * из t1, t2, где t1.country = 'US' и t2.country = t1.country и t1.id = t2.id

потому что, если я хочу изменить литерал, нужно только одно изменение.

1 голос
/ 16 сентября 2008

У меня была похожая ситуация, и к этому решению я прибегнул:

Выбрать * ОТ Т1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ t2 ON t1.id = t2.id AND t1.country = t2.country AND t1.country = 'US'

Я заметил, что мой запрос выполнялся быстрее в этом сценарии. Я сделал предположение, что соединение с константой сэкономило время двигателя, потому что предложение WHERE будет выполнено в конце. Присоединение и последующая фильтрация по «США» означает, что вы все же вытащили из таблицы все другие страны, а затем отфильтровали те, которые хотели. В конце концов, этот метод извлекает меньше записей, потому что он находит только записи США.

1 голос
/ 16 сентября 2008

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

1 голос
/ 16 сентября 2008

Правильный ответ, вероятно, зависит от вашего движка SQL. Для MS SQL Server первый подход явно лучше, поскольку статистическому оптимизатору предоставляется дополнительная подсказка, которая может помочь ему найти лучший (более оптимальный) путь разрешения.

0 голосов
/ 16 сентября 2008

Вместо того, чтобы использовать неявное внутреннее соединение, я бы явно соединял таблицы.

Поскольку вы хотите, чтобы поля id и поля страны были одинаковыми, и вы упомянули, что оба они проиндексированы (я предполагаю, что в одном и том же индексе), я бы включил оба столбца в объединение, чтобы вы могли использовать поиск по индексу вместо сканирования. Наконец, добавьте предложение where.

SELECT *
  FROM t1
  JOIN t2 ON t1.id = t2.id AND t1.country = t2.country
 WHERE t1.country = 'US'

0 голосов
/ 16 сентября 2008

Я думаю, что лучше SQL будет:

выберите * из t1, t2, где t1.id = t2.id и t1.country = 'US'

Нет необходимости использовать второе сравнение с «США», если только возможно, что страна в t2 может отличаться от t1 для того же идентификатора.

0 голосов
/ 16 сентября 2008

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

Я бы предложил использовать функцию EXPLAIN, чтобы выяснить, какое из выражений является наиболее оптимальным.

0 голосов
/ 16 сентября 2008

Я подозреваю, что это будет зависеть от таблиц, данных и метаданных. Я ожидаю, что смогу создать примеры, которые будут показывать результаты в обоих направлениях - тест!

0 голосов
/ 16 сентября 2008

Если вы когда-нибудь захотите сделать запрос более общим, возможно, заменив параметр для целевой страны, я бы пошел с вашим первым примером, поскольку он требует только одного изменения. Меньше беспокоиться о том, что в будущем вы ошибетесь.

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