В качестве примера вы выбрали один из немногих случаев, когда одно дерево не может выполнить работу (два независимых диапазона).
Тем не менее, первая глава моей электронной книги о незавершенном производстве объясняет внутреннюю работу индексов B-Tree: http://use -the-index-luke.com / anatomy /
РЕДАКТИРОВАТЬ для более подробной информации, почему два индекса могут быть полезны для приведенного выше примера.
Приведенный выше запрос может поддерживаться тремя возможными конфигурациями индекса:
каскадный индекс для AGE
и затем WEIGHT
(в этом порядке).
В этом случае запрос будет читать все записи WHERE AGE > 50
, а затем фильтровать по WEIGHT
.
каскадный индекс для WEIGHT
и затем AGE
(другой порядок).
Это происходит по-другому: читать все записи WHERE WEIGHT < 100
, а затем фильтровать по AGE
.
Все, что является более эффективным, зависит от имеющихся у вас данных. Если записей меньше AGE > 50
, чем WEIGHT < 100
, первая будет более эффективной, иначе вторая. Однако при запросе с другими значениями картина может измениться.
Причиной того, что составной индекс не может хорошо поддерживать запрос, является то, что каждый порядок индексов находится только на одной оси. каждая запись индекса до или после другой, но никогда рядом с ней. Все записи индекса строят одну цепочку.
Запрос, который имеет два независимых запроса диапазона, потребует двух осей, не как цепочка, а скорее как шахматная доска. одна ось для AGE
другая для WEIGHT
. Если это возможно, ваш запрос должен будет сканировать только один угол шахматной доски.
Однако b-дерево имеет только одну ось, поэтому вы должны выбрать, какие критерии использовать в первую очередь. Если вы выбрали AGE
, это означает, что, начиная с AGE 50
, вся цепочка будет сканироваться до конца. Только некоторые из записей, хранящихся на боковой цепочке, также будут иметь право на WEIGHT < 100
, остальные записи должны быть прочитаны, но будут отброшены.
Итак, длинная история, объясняющая, почему одно дерево не может поддерживать запрос с двумя независимыми предложениями диапазона. С другой стороны, один составной индекс может хорошо выполнять следующие действия:
WHERE age = 50 AND weight < 100
WHERE weight = 100 AND age > 50
WHERE age > 50 AND age < 70;
Однако проблема возникает, если в двух разных столбцах используются два оператора неравенства.
Итак, что делать?
Третий возможный подход состоит в том, чтобы иметь два независимых индекса в двух столбцах. Это позволяет иметь столько осей, сколько вам нужно (просто создайте больше индексов). Однако есть несколько огромных проблем с этим. Прежде всего, не все продукты DB поддерживают это. Всякий раз, когда это поддерживается, это довольно обширная операция. Обычно он работает таким образом, что каждый индекс сканируется, для каждого результата создается индекс bitmap . Затем эти растровые индексы объединяются для применения оператора AND
. Это очень много данных - стоит потраченных усилий только в том случае, если каждое условие не очень избирательно для себя, но оба вместе очень избирательно.
Разве не мой совет?
Если ваш запрос выполняется в среде OLTP: используйте один составной индекс.
Два независимых индекса являются опцией только в крайнем случае. Однако если вы работаете в среде OLAP, в любом случае вам могут понадобиться растровые индексы.
пс .:
Индексирование AGE
было упражнением в моей книге (с решением) - особенно потому, что хранение AGE
- плохая практика, вместо этого вам следует хранить дату рождения.