Порядок таблиц, на которые ссылаются в НА пункте вопроса СОЕДИНЕНИЯ?

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

35
задан Even Mien 24 April 2009 в 12:09
поделиться

7 ответов

Порядок

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

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

    При этом будет использоваться индекс b.id :

     SELECT a.Name, b.Status
    Из
    STRAIGHT_JOIN
     б
    ON b.ID = a.StatusID
    

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

     ВЫБРАТЬ a.Name, b.Status
    ОТ Б
    STRAIGHT_JOIN
     
    ON b.ID = a.StatusID
    
  2. Oracle имеет специальную подсказку ORDERED для обеспечения порядка JOIN :

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

     ВЫБРАТЬ / * + ЗАКАЗАТЬ * /
     *
    Из
    ПРИСОЕДИНЯЙТЕСЬ к b
    ON b.ID = a.StatusID
    

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

     SELECT / * + ORDERED * /
     *
    ОТ Б
    Присоединиться к
    ON b.ID = a.StatusID
    
  3. SQL Server имеет подсказку под названием FORCE ORDER , чтобы сделать то же самое:

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

     SELECT *
    Из
    ПРИСОЕДИНЯЙТЕСЬ к b
    ON b.ID = a.StatusID
    ВАРИАНТ (ПРИНЯТЬ СИЛУ)
    

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

     SELECT *
    ОТ Б
    Присоединиться к
    ON b.ID = a.StatusID
    ВАРИАНТ (ПРИНЯТЬ СИЛУ)
    
  4. Ребята из PostgreSQL, извините. Ваш список TODO гласит:

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

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

Что касается порядка в сравнении, то это не имеет значения ни в одной СУБД , AFAIK.

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

См. этот ответ для более подробной информации.

33
ответ дан 27 November 2019 в 07:14
поделиться

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

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

9
ответ дан 27 November 2019 в 07:14
поделиться

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

5
ответ дан 27 November 2019 в 07:14
поделиться

No there is not. At the end of the day, you are really just evaluating whether a=b.

And as the symmetric property of equality states:

  • For any quantities a and b, if a = b, then b = a.

so whether you check for (12)*=12 or 12=(12)* makes logically no difference.

If values are equal, join, if not, don't. And whether you specify it as in your first example or the second, makes no difference.

3
ответ дан 27 November 2019 в 07:14
поделиться

Read this

SqlServer contains an optimisation for situations far more complex than this.

If you have multiple criteria stuff is usually lazy evaluated (but I need to do a bit of research around edge cases if any.)

For readability I usually prefer

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

I think it makes better sense to reference the variable in the same order they were declared but its really a personal taste thing.

1
ответ дан 27 November 2019 в 07:14
поделиться

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

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

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

Исправление: результат не изменится.

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

0
ответ дан 27 November 2019 в 07:14
поделиться

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

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

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

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

0
ответ дан 27 November 2019 в 07:14
поделиться
Другие вопросы по тегам:

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