Oracle SQL IN: выполняется ли это последовательно? - PullRequest
0 голосов
/ 25 июля 2011

TableX

number doc
number item
number parentItem

С данными:

1, 1000, 0
1, 1010, 1000
1, 1020, 1000
1, 2000, 0
1, 2010, 2000

ТаблицаY

number doc
number item
varchar2(16) SomeData

С данными:

1, 1000, "1000 Data"
1, 2000, "2000 Data"

Я использую следующий SQL-запрос, чтобы получить «SomeData» из таблицы Y

select x.doc, x.item, y.SomeData from TableX x
join TableY y
on y.doc = x.doc and y.item IN (x.item, x.ParentItem)

, что должно привести к:

1, 1000, "1000 Data"
1, 1010, "1000 Data"
1, 1020, "1000 Data"
1, 2000, "2000 Data"
1, 2010, "2000 Data"

Мой вопрос таков: IN-Statement оценивается последовательно, или это зависит от пути Oracle?

Редактировать Что я имею в виду, когда есть запись в TableY для элемента из TableX (например, 1000), будет ли это значение сначала использоваться в JOIN или ParentItem будет использоваться первым?Или JOIN на ParentItem включен только тогда, когда не удается выполнить JOIN на элементе?

Ответы [ 2 ]

4 голосов
/ 25 июля 2011

Обычно при работе с базами данных порядок отсутствует, если только вы его не указали.Я считаю, что IN всегда проверяет весь список, а не замыкает накоротко, когда находит совпадение, но нет никакой гарантии относительно порядка, в котором будет обрабатываться список (не имеет значения, проверяет ли он весь список).


Исходя из вашего пересмотренного вопроса:

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

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

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

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

0 голосов
/ 25 июля 2011

Порядок оценки не имеет значения.Оператор IN - это просто сокращенный способ сказать y.item = x.item OR y.item = x.ParentItem OR ....

...