Я всегда стараюсь поместить выражения в JOIN
в следующем порядке:
joined.column = leading.column
Этот запрос:
SELECT t.value, d.name
FROM transactions t
JOIN
dimensions d
ON d.id = t.dimension
может рассматриваться как «для каждой транзакции, найти соответствующее имя измерения», или «для каждого измерения, найти все соответствующие значения транзакции».
Итак, если я ищу данную транзакцию, я помещаю выражения в следующем порядке:
SELECT t.value, d.name
FROM transactions t
JOIN
dimensions d
ON d.id = t.dimension
WHERE t.id = :myid
, и если я ищу измерение, то:
SELECT t.value, d.name
FROM dimensions d
JOIN
transactions t
ON t.dimension = d.id
WHERE d.id = :otherid
Первый запрос, скорее всего, будет использовать сканирование индекса сначала на (t.id)
, затем на (d.id
), тогда как последний будет использовать сканирование индекса сначала на (d.id)
, затем на (t.dimension)
, и вы можете легко увидеть это в самом запросе: искомые поля находятся слева.
Управляющие и ведомые таблицы могут быть не столь очевидны в JOIN
, но это так же ясно, как колокольчик для запроса CONNECT BY
: строка PRIOR
движется, а не PRIOR
движется.
Вот почему этот запрос:
SELECT *
FROM hierarchy
START WITH
id = :root
CONNECT BY
parent = PRIOR id
означает «найти все строки, для которых parent
является заданным id
». Этот запрос строит иерархию.
Это можно трактовать так:
connect_by(row) {
add_to_rowset(row);
/* parent = PRIOR id */
/* PRIOR id is an rvalue */
index_on_parent.searchKey = row->id;
foreach child_row in index_on_parent.search {
connect_by(child_row);
}
}
И этот запрос:
SELECT *
FROM hierarchy
START WITH
id = :leaf
CONNECT BY
id = PRIOR parent
означает «найти строки, для которых id
является заданным parent
». Этот запрос создает цепочку предков.
Всегда ставьте PRIOR
в правой части выражения.
Думайте о PRIOR column
как о константе, в которой будут выполняться поиск во всех ваших строках.