SQLite объединяет несколько значений из двух таблиц [duplicate]

C ++ делает это так, потому что C сделал это так, поэтому реальный вопрос - почему C сделал это так? Википедия немного говорит об этом.

Новые скомпилированные языки (такие как Java, C #) не используют форвардные объявления; идентификаторы автоматически распознаются из исходных файлов и считываются непосредственно из динамических символов библиотеки. Это означает, что файлы заголовков не нужны.

144
задан Steve Dignan 19 June 2009 в 17:49
поделиться

9 ответов

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

Я рекомендую вам писать запросы в наиболее читаемом

Иногда это включает в себя включение INNER JOIN относительно «неполного» и включение некоторых критериев в WHERE просто для составления списков

Например, вместо:

  SELECT * FROM Customers c INNER JOIN CustomerAccounts ca ON ca.CustomerID = c.CustomerID И c.State  = 'NY' INNER JOIN Учетные записи a ON ca.AccountID = a.AccountID AND a.Status = 1  

Запись:

  SELECT * FROM Customers c  INNER JOIN CustomerAccounts ca ON ca.CustomerID = c.CustomerID INNER JOIN Счета a ON ca.Acc  ountID = a.AccountID WHERE c.State = 'NY' AND a.Status = 1  

Но это зависит, конечно.

116
ответ дан Cade Roux 16 August 2018 в 04:54
поделиться
  • 1
    Для добавления это зависит. Контролируйте все. – marr75 19 June 2009 в 18:02
  • 2
    Речь идет не только о чистом запросе или читаемости, но и о производительности. включение условий в соединение повышает производительность для большого количества данных с правильно проиндексированными таблицами. – Shahdat 6 October 2016 в 15:13
  • 3
    Я просто запускаю ежемесячные отчеты о продажах, вступая в 5-6 таблиц на несколько миллионов записей. Perf улучшается на 30% - сервере sql 2012 – Shahdat 6 October 2016 в 16:33
  • 4
    @Shahdat, если вы получаете значительную разницу в производительности, перемещая условия фильтра из предложения where во внутреннее соединение, вам нужно опубликовать эти планы выполнения. – Cade Roux 6 October 2016 в 16:36
  • 5
    @Cade Я исследовал планы выполнения - оба сценария показывают одинаковые затраты. Я запускаю запросы несколько раз, кажется, что и то же самое касается времени. Раньше я запускал запросы на производство и получал значительную разницу в производительности, потому что база данных использовалась живыми пользователями. Извините за эту путаницу. – Shahdat 18 October 2016 в 16:22

Большинство продуктов RDBMS будут оптимизировать оба запроса одинаково. В «настройке производительности SQL» Питера Гулуцана и Труди Пельцер они протестировали несколько брендов РСУБД и не обнаружили разницы в производительности.

Я предпочитаю сохранять условия соединения отдельно от условий ограничения запроса.

Если вы используете OUTER JOIN , иногда необходимо добавить условия в предложение join.

21
ответ дан Bill Karwin 16 August 2018 в 04:54
поделиться
  • 1
    Я согласен с вами в том, что синтаксически это чище, и я должен отнестись к вашим знаниям этой книги и вашей очень высокой репутации, но я могу представить 4 вопроса на прошлой неделе с очень разными планами выполнения, временем процессора и логическими чтениями, когда Я переехал туда, где предикаты к соединению. – marr75 19 June 2009 в 17:58
  • 2
    Вы спрашивали о лучших практиках. Как только вы приступите к тестированию того, как работает конкретная реализация RDBMS, другие люди дали правильный совет: бенчмарк. – Bill Karwin 19 June 2009 в 18:09

Объединяется быстрее, на мой взгляд, когда у вас большой стол. Это действительно не такая уж большая разница, особенно если вы имеете дело с довольно маленькой таблицей. Когда я впервые узнал о объединениях, мне сказали, что условия в соединениях аналогичны условиям условий предложения и что я могу использовать их взаимозаменяемо, если предложение where было специфическим для какой таблицы выполнить условие.

0
ответ дан Eric 16 August 2018 в 04:54
поделиться

Полагая условие в соединении кажется мне «семантически неправильным», поскольку это не то, что JOINs «для». Но это очень качественно.

Дополнительная проблема: если вы решили переключиться с внутреннего соединения на, скажем, правое соединение, имея условие внутри JOIN, это может привести к неожиданным результатам.

0
ответ дан Jacob B 16 August 2018 в 04:54
поделиться
  • 1
    Иногда эти результаты являются «ожидаемыми» и «ожидаемыми». и иногда даже "преднамеренное" (например, с внешними соединениями, где условие WHERE имеет разную семантику, чем условие JOIN). – Thetam 30 May 2012 в 14:30

Лучше добавить условие в Join. Производительность важнее, чем читаемость. Для больших наборов данных это важно.

0
ответ дан Jeeno Shibu 16 August 2018 в 04:54
поделиться

Я предпочитаю, чтобы JOIN присоединился к полным таблицам / представлениям, а затем использовал WHERE Чтобы ввести предикат результирующего набора.

Он чувствует себя синтаксически чистым.

3
ответ дан Johnno Nolan 16 August 2018 в 04:54
поделиться

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

Я всегда слегка удивляюсь, когда кто-то показывает их бенчмаркинг SQL, и они выполнили обе версии sproc 50 000 раз в полночь на сервере dev и сравнили среднее время.

2
ответ дан marr75 16 August 2018 в 04:54
поделиться

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

Однако, когда вы ставите условие, это имеет огромное значение если вы используете левое или правое соединение. Например, рассмотрите эти два запроса:

  SELECT * FROM dbo.Customers AS CUS LEFT JOIN dbo.Orders AS ORD ON CUS.CustomerID = ORD.CustomerID WHERE ORD.OrderDate & gt; '20090515' SELECT  * FROM dbo.Customers AS CUS LEFT JOIN dbo.Orders AS ORD ON CUS.CustomerID = ORD.CustomerID AND ORD.OrderDate & gt; '20090515'  

Первый даст вам только те записи которые имеют приказ от 15 мая 2009 года, таким образом преобразовывая левое соединение во внутреннее соединение. Второй даст эти записи плюс любые клиенты без заказов. Набор результатов очень отличается в зависимости от того, где вы положили условие. (Выберите *, если, например, только для целей, вы не должны использовать, конечно, производственный код.) Исключением является то, что вы хотите видеть только записи в одной таблице, а не другую. Затем вы используете предложение where для условия, а не соединения.

  SELECT * FROM dbo.Customers AS CUS LEFT JOIN dbo.Orders AS ORD ON CUS.CustomerID = ORD.CustomerID ГДЕ ORD.OrderID - null  
91
ответ дан PW. 16 August 2018 в 04:54
поделиться
  • 1
    Спасибо, что объяснили с примерами – Rennish Joseph 15 April 2017 в 15:00
  • 2
    Большой ответ - ясный и актуальный для ОП – psrpsrpsr 13 February 2018 в 16:08
  • 3
    "таким образом, преобразование левого соединения в внутреннее соединение". Как? Можете ли вы немного разобраться? – user1451111 16 April 2018 в 14:57

WHERE будет фильтроваться после того, как произошел JOIN.

Фильтр в JOIN, чтобы предотвратить добавление строк во время процесса JOIN.

8
ответ дан TheTXI 16 August 2018 в 04:54
поделиться
  • 1
    Семантически, они предотвращаются во время процесса INNER JOIN, но оптимизатор может переупорядочить INNER JOIN и WHERE предикаты по желанию, поэтому оптимизатор может свободно исключать их позже, если захочет. – Cade Roux 19 June 2009 в 18:02
  • 2
    Cade Roux: Верно. Часто то, что вы пишете в SQL, не то, что оптимизатор даст вам, когда все будет сказано и сделано. Тогда я бы предположил, что это будет правильно в мире теории теории, в то время как ваш ответ, конечно, более правильный в мире автоматических оптимизаторов запросов :) – TheTXI 19 June 2009 в 18:09
Другие вопросы по тегам:

Похожие вопросы: