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

Описывает ли порядок таблиц, упомянутых в предложении ON для дела JOIN?

Имеет ли значение, каким образом я заказываю критерии в предложении ON для JOIN?

select a.Name, b.Status from a
inner join b
on a.StatusID = b.ID

против

select a.Name, b.Status from a
inner join b
on b.ID = a.StatusID

Есть ли влияние на производительность? Что делать, если у меня было несколько критериев?

Является ли один заказ более удобным, чем другой?

4b9b3361

Ответ 1

JOIN порядок может быть принудительно, поместив таблицы в правильном порядке в предложение FROM:

  • MySQL имеет специальное предложение, называемое STRAIGHT_JOIN, которое делает вопрос порядка.

    Это будет использовать индекс на b.id:

    SELECT  a.Name, b.Status
    FROM    a
    STRAIGHT_JOIN
            b
    ON      b.ID = a.StatusID
    

    И это будет использовать индекс на a.StatusID:

    SELECT  a.Name, b.Status
    FROM    b
    STRAIGHT_JOIN
            a
    ON      b.ID = a.StatusID
    
    • Oracle имеет специальный подсказку ORDERED для обеспечения порядка JOIN:

    Это будет использовать индекс на b.id или построить хеш-таблицу на b:

    SELECT  /*+ ORDERED */
            *
    FROM    a
    JOIN    b
    ON      b.ID = a.StatusID
    

    И это будет использовать индекс на a.StatusID или построить хеш-таблицу на a:

    SELECT  /*+ ORDERED */
            *
    FROM    b
    JOIN    a
    ON      b.ID = a.StatusID
    
    • SQL Server имеет подсказку, называемую FORCE ORDER, чтобы сделать то же самое:

    Это будет использовать индекс на b.id или построить хеш-таблицу на b:

    SELECT  *
    FROM    a
    JOIN    b
    ON      b.ID = a.StatusID
    OPTION (FORCE ORDER)
    

    И это будет использовать индекс на a.StatusID или построить хеш-таблицу на a:

    SELECT  *
    FROM    b
    JOIN    a
    ON      b.ID = a.StatusID
    OPTION (FORCE ORDER)
    

    подсказки оптимизатора (не нужны)

         
      

    Рекомендации оптимизатора используются для решения проблем в оптимизаторе. Мы бы предпочли сообщить и зафиксировать проблемы.

      

Что касается порядка в сравнении, это не имеет значения ни в одном RDBMS, AFAIK.

Хотя я лично всегда стараюсь оценить, какой столбец будет искать, и поместить этот столбец влево (чтобы он выглядел как lvalue).

Подробнее см. этот ответ.

Ответ 2

Нет, это не так.

То, что я делаю (для читаемости), является вашим вторым примером.

Ответ 3

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

Ответ 4

Нет, нет. В конце дня вы действительно просто оцениваете, является ли a = b.

И поскольку симметричное свойство равенства гласит:

  • Для любых величин a и b, если a = b, то b = a.

поэтому, если вы проверяете наличие (12)*=12 или 12=(12)*, то логически не будет различий.

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

Ответ 5

Прочтите это

SqlServer содержит оптимизацию для ситуаций, гораздо более сложных, чем это.

Если у вас есть несколько критериев, материал обычно ленится (но мне нужно сделать немного исследований по крайним случаям, если они есть.)

Для удобства чтения я обычно предпочитаю

SELECT Name, Status FROM a 
JOIN b 
ON a.StatusID = b.ID

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

Ответ 6

Единственная причина, по которой я не буду использовать ваш второй пример:

select a.Name, b.Status 
from a
inner join b
  on b.ID = a.StatusID

Ваш пользователь, скорее всего, вернется и скажет: "Могу ли я увидеть все имя a.name, даже если у них нет записей о состоянии?" а не "Могу ли я увидеть все b.status, даже если у них нет записи имен?", поэтому просто для планирования вперед в этом примере я бы использовал On a.StatusID = b.ID в ожидании LEFT Outer Join. Это предполагает, что у вас может быть таблица "a" без "b".

Коррекция: он не изменит результат.

Это, вероятно, спорный момент, поскольку пользователи никогда не хотят менять свои требования.

Ответ 7

Как многие говорили: порядок не влияет на результат или производительность.

Я хочу отметить, что LINQ to SQL допускает только первый случай!

Например, следующий пример хорошо работает,...

var result = from a in db.a
             join b in db.b on a.StatusID equals b.ID
             select new { Name = a.Name, Status = b.Status }

... в то время как это вызовет ошибки в Visual Studio:

var result = from a in db.a
             join b in db.b on b.ID equals a.StatusID
             select new { Name = a.Name, Status = b.Status }

Что вызывает эти ошибки компилятора:

  • CS1937: имя "имя" не находится в области действия в левой части "равно". Рассмотрим замену выражений по обе стороны от "равно".
  • CS1938: имя "имя" не находится в области действия с правой стороны от "равно". Рассмотрим замену выражений по обе стороны от "равно".

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

Ответ 8

нет, не имеет значения. но вот пример, который поможет сделать ваши запросы более читабельными (по крайней мере для меня).

select a.*, b.*
from tableA a
     inner join tableB b
          on a.name=b.name
               and a.type=b.type

каждая таблица ссылается на отдельную строку, и каждый критерий соединения находится на отдельной строке. tabbing помогает сохранить то, что принадлежит тому, что прямо.

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