Подтвердить что ты не робот

ANSI и не ANSI SQL JOIN синтаксис

У меня есть моя бизнес-логика в ~ 7000 строк хранимых процедур T-SQL, и у большинства из них следующий синтаксис JOIN:

SELECT A.A, B.B, C.C
FROM aaa AS A, bbb AS B, ccc AS C
WHERE
    A.B = B.ID
AND B.C = C.ID
AND C.ID = @param

Я получу рост производительности, если я заменил такой запрос следующим:

SELECT A.A, B.B, C.C
FROM aaa AS A
JOIN bbb AS B
   ON A.B = B.ID
JOIN ccc AS C
   ON B.C = C.ID
   AND C.ID = @param

Или они одинаковы?

4b9b3361

Ответ 1

Два запроса одинаковы, кроме второго - синтаксис SQL ANSI-92, а первый - старший синтаксис SQL, который не включает предложение join. Они должны составить точно такой же внутренний план запросов, хотя вы можете проверить его.

Вы должны использовать синтаксис ANSI-92 по нескольким причинам.

  • Использование предложения JOIN разделяет логика отношений с (ГДЕ) и, таким образом, чище и понятнее.
  • Это не имеет значения с этим конкретным запросом, но есть несколько обстоятельств, когда более старый внешний синтаксис соединения (с использованием +) неоднозначен, и результаты запроса, следовательно, зависят от реализации - или запрос не может быть разрешен вообще. Это не происходит с ANSI-92
  • Это хорошая практика, так как большинство разработчиков и dba будут использовать ANSI-92 в настоящее время, и вы должны следовать стандарту. Конечно, все современные инструменты запросов будут генерировать ANSI-92.
  • Как указано в @gbn, он имеет тенденцию избегать случайных кросс-соединений.

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

Ответ 2

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

Обычные аргументы выглядят следующим образом:

Плюсы "традиционного" синтаксиса: предикаты физически группируются в предложении WHERE в любой порядок, который делает запрос в целом, и n-ary отношения, в частности, легче читать и понимать (предложения ON синтаксиса infixed могут распространять предикаты, поэтому вам нужно искать появление одной таблицы или столбца над визуальное расстояние).

Недостатки синтаксиса "Традиционный": при исключении одного из предикатов "join" отсутствует ошибка синтаксического анализа, и результатом является декартово произведение (известное как CROSS JOIN в синтаксисе infixed), и такая ошибка может быть сложно обнаружить и отладить. Кроме того, предикаты "join" и предикаты "фильтрации" физически группируются в предложении WHERE, что может привести к их смущению друг от друга.

Ответ 3

Выполните оба и проверьте свои планы запросов. Они должны быть равными.

Ответ 4

Два запроса равны - первый использует синтаксис ANSI JOIN, второй - синтаксис ANSI JOIN. Я рекомендую придерживаться синтаксиса ANSI JOIN.

И да, LEFT OUTER JOINs (которые, кстати, также являются синтаксисом ANSI JOIN) - это то, что вы хотите использовать, когда есть вероятность, что таблица, в которую вы присоединяетесь, может не содержать соответствующих записей.

Ссылка: Условные соединения в SQL Server

Ответ 5

ОК, они выполняют то же самое. Это согласилось. В отличие от многих, я использую более старую конвенцию. То, что SQL-92 "легче понять", является спорным. Записав языки программирования для 40 лет (gulp), я знаю, что "легко читаемый" начинается сначала перед любым другим соглашением с "остротой зрения" (здесь используется неверный термин, но это лучшая фраза, которую я могу использовать). При чтении SQL ПЕРВАЯ вещь, о которой вы беспокоитесь, касается того, какие таблицы задействованы, а затем какая таблица (большинство) определяет зерно. Затем вы заботитесь о соответствующих ограничениях на данные, а затем выбранные атрибуты. В то время как SQL-92 в основном отделяет эти идеи, существует так много шумовых слов, мозг должен интерпретировать и обрабатывать их, и это делает чтение SQL медленнее.

SELECT Mgt.attrib_a   AS attrib_a
      ,Sta.attrib_b   AS attrib_b
      ,Stb.attrib_c   AS attrib_c
FROM   Main_Grain_Table  Mgt
      ,Surrounding_TabA  Sta
      ,Surrounding_tabB  Stb
WHERE  Mgt.sta_join_col  = Sta.sta_join_col
AND    Mgt.stb_join_col  = Stb.stb_join_col
AND    Mgt.bus_logic_col = 'TIGHT'

Острота зрения! Поместите запятые для новых атрибутов впереди. Он также упрощает код комментирования. Используйте конкретный случай для функций и ключевых слов Используйте конкретный случай для таблиц Использовать конкретный случай для атрибутов Вертикально Выстраивать операторы и операции Сделать первую таблицу в FROM представляют зернистость данных Сделайте первые таблицы WHERE равными ограничениям объединения, и пусть конкретные, жесткие ограничения будут плавать в нижней части. Выберите 3 символа псевдонима для ВСЕХ таблиц в вашей базе данных и используйте псевдоним КАЖДЫЙ, с которым вы ссылаетесь на таблицу. Вы должны использовать этот псевдоним в качестве префикса для (многих) индексов на этой таблице. 6 из 1 1/2 десятка другого, не так ли? Может быть. Но даже если вы используете соглашение ANSI-92 (как и я, и в случае продолжения работы), используйте принципы остроты остроты зрения, выравнивание по вертикали, чтобы ваш мысленный взгляд мог не попасть в места, которые вы хотите видеть, и легко избегать вещей (особенно шумовые слова) вам не нужно.

Ответ 6

В моем представлении предложение FROM - это то, где я решаю, какие столбцы мне нужны в строках для моего предложения SELECT. Здесь выражается бизнес-правило, которое выводит на ту же строку, значения, необходимые в вычислениях. Бизнес-правило может быть клиентом, у которого есть счета-фактуры, в результате чего строятся счета-фактуры, включая ответственность клиента. Это также могут быть места в том же почтовом индексе, что и клиенты, в результате чего список мест и клиентов, которые находятся близко друг к другу.

Здесь я определяю центричность строк в моем результирующем наборе. В конце концов, нам просто показана метафора списка в РСУБД, причем в каждом списке есть тема (сущность), и каждая строка является экземпляром объекта. Если понимать центричность строк, понимается объект набора результатов.

Предложение WHERE, которое концептуально выполняется после строк, определено в предложении from, отбирает строки, которые не требуются (или содержат строки, которые требуются) для предложения SELECT для работы.

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

то есть. Я не буду писать предложение WHERE следующим образом:

 WHERE Column1 = Column2

Я поставлю это в предложение FROM следующим образом:

 ON Column1 = Column2

Аналогично, если столбец следует сравнивать с внешними значениями (значениями, которые могут быть или не быть в столбце), например, сравнение почтового индекса с конкретным почтовым индексом, я поставлю это в предложение WHERE, потому что я в основном говорю Мне нужны только такие строки.

то есть. Я не буду писать предложение FROM следующим образом:

 ON PostCode = '1234'

Я поставлю это в предложение WHERE следующим образом:

 WHERE PostCode = '1234'

Ответ 7

Синтаксис ANSI не применяет ни предикативное размещение в правильном предложении (будь то ON или WHERE), ни близость предложения ON к смежной таблице. Разработчик может свободно писать беспорядок

SELECT
   C.FullName,
   C.CustomerCode,
   O.OrderDate,
   O.OrderTotal,
   OD.ExtendedShippingNotes
FROM
   Customer C
   CROSS JOIN Order O
   INNER JOIN OrderDetail OD
      ON C.CustomerID = O.CustomerID
      AND C.CustomerStatus = 'Preferred'
      AND O.OrderTotal > 1000.0
WHERE
   O.OrderID = OD.OrderID;

Говоря о инструментах запросов, которые "будут генерировать ANSI-92", я комментирую здесь, потому что он сгенерировал

SELECT 1
   FROM DEPARTMENTS C
        JOIN EMPLOYEES A
             JOIN JOBS B
     ON C.DEPARTMENT_ID = A.DEPARTMENT_ID
     ON A.JOB_ID = B.JOB_ID

Единственным синтаксисом, который избегает обычного "файла с ограничением-проектом-декартово", является внешнее соединение. Эта операция сложнее, потому что она не ассоциативна (как с самим собой, так и с нормальным соединением). Нужно, по крайней мере, разумно заключить в круг запрос с внешним соединением. Однако это экзотическая операция; если вы слишком часто используете его, я предлагаю использовать класс реляционных баз данных.