Программирование >>  Полное сканирование таблицы 

1 ... 12 13 14 [ 15 ] 16 17 18 ... 107


нюю границу диапазона всех возможных значений, то сможете использовать сканирование диапазона с условием, например, Positi velDColumn > -1 or Date Co1umn > TO DATE(0001/01/01. УУУУ/ММ/ОО).

Условие Indexecl Char Col LIKE АВСЖ устанавливает начальную и конечную точки допустимого диапазона для индекса, причем Indexed Char Co1 является ведущим столбцом индекса. Схожим образом работает блок сравнения шаблонов в SQL, где % является символом подстановки.

Условие Indexed Char Col LIKE ABCXDEF также задает начальную и конечную точки допустимого диапазона, но в этом сл5П1ае только часть №£% сужает диапазон сканирования индекса.

Условие Indexed Nuniber Co1umn LIKE 123% не устанавливает начальную и конечную точки допустимого диапазона, так как сравнение LIKE имеет смысл только для строк символов. В этом случае серверу для проверки условия необходимо неявно преобразовать Indexed Number Co1umn в строку символов, делая невозможным применение любого индекса, для которого ведущим является столбец Indexed Number Co1 umn. В терминах чисел это условие задает целую группу диапазонов:

(Indexed Number Column >= 123 AND Indexed Number Co1unin < 124) OR (Indexed Number Column >= 1230 AND Indexed Number Co1umn <1240) OR (Indexed Number Co1umn >= 12300 AND Indexed Number Co1umn < 12400) OR...

Условие Indexed Char Co1 LIKE %№£% вообще не задает начальную и конечную точки допустимого диапазона, так как стартовый символ подстановки указы-

, вает, что этот шаблон может появиться в любом месте индекса.

Равенство (=), BETWEEN и большинство неравенств (<, <=, >, >=) для первых столбцов индексов устанавливают допустимые конечные точки диапазона индекса.

Неравенство вида не равно , которое обычно выражается как != или <>, не устанавливает диапазон индекса, так как база данных не считает такое условие достаточно селективным, чтобы использовать для него индексный доступ. Если исключенное значение покрывает практически все строки, а другие значения встречаются редко, можно включить индексный доступ, заменив условие Column!=DominantVa1ue на Column IN (<список остальных, редко встречающихся зна-чвний>), хотя с изменением приложения с течением времени такой подход может стать неудобным.

Использование групп условий, объединенных при помощи OR или в списке IN, может привести к выполнению последовательности операций сканирования диапазонов, но только если каждое из этих условий указывает на допустимый диапазон. Например, IDColumn IN (123.124.125) преобразуется в три допустимых условия равенства, для которых выполняется сканирование трех диапазонов. Условие (Name= Smi th OR Name= Jones) приводит к сканированию двух диапазонов, однако (Name= Smi th OR Name IS NULL) не разрешает использовать индекс (кроме DB2), так как IS NULL не указывает на допустимый диапазон.

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



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

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

Селективность для строк таблицы, полученных при помощи индекса

Так как индексы - это компактные и обычно хорошо кэшированные объекты по сравнению с таблицами, селективность сканирования диапазона индекса значит меньше, чем эффективный доступ к таблице. Даже когда индекс и таблица идеально кэшированы, селективность для таблицы важнее, чем для индекса, так как вы считываете около 300 строк индекса в листовом блоке одной операцией логического ввода-вывода, но должны выполнять отдельную операцию логического ввода-вывода для каждой строки таблицы. Так мы приходим ко второй части оценки полезности индекса: насколько сильно индекс может сузить доступ к таблице? К счастью, производители баз данных достаточно умны, чтобы проверить все условия как можно раньше в плане выполнения, еще до обращения к таблице, где это позволяет сделать индекс. Это сокращает количество считываний данных из таблицы, когда индекс содержит столбцы, необходимые для оценки условия, - даже если база данных не может при помощи этого условия определить конечные точки диапазона сканирования. Например, рассмотрим таблицу Persons с одним индексом, втслючающим столбцы Area Code. Phone Number. Last Name и Fi rst Name. Возьмем запрос к этой таблице с условиями: WHERE Агеа Сос1е=91б AND UPPER(F1rst Name)=-IVA

Только первое условие позволяет определить конечные точки диапазона сканирования индекса. Второе условие, по четвертому индексированному столбцу, не может сузить диапазон по трем причинам.

Для второго столбца индекса, Phone Number, не указано условий равенства (по большому счету, для него вообще нет условий).

Для третьего столбца индекса, LastName, также не указаны условия равенства.

Условие для Fi rstName не в состоянии ограничить диапазон из-за функции UPPER.

К счастью, ни одна из этих причин не запрещает базе данных проверить второе условие до обращения к таблице. Так как в индексе есть столбец Fi rstName, база



данных может проверить условия для этого столбца при помощи данных из индекса. В этом случае база данных использует условие Area Code для определения диапазона сканирования индекса. Затем она просматривает все записи индекса в диапазоне и отметает записи, в которых имена не равны Iva. Вероятный результат по этой селективной комбинации условий - одно или два считывания из таблицы.

Давайте изучим эту ситуацию подробнее и решим, стоит ли создавать для этой комбинации условий лучший индекс. Как для Area Code, так и для Fi rst Name мы увидим несимметричное распределение. Чаще всего будут запрашиваться наиболее распространенные коды областей и имена, поэтому используем стандартный подход к несимметричным распределениям и найдем отдельные значения селективности: ,Ч .

SELECT SUM(COUNT(Area Ccde)*COUNT(Area Code))/

(SUM(COUNT(Area Code))*SUM(COUNT(*)))

FROM Customers GROUP BY Area Code:

SELECT SUM(C0UNT(First Name)*C0UNT(F1rst Nanie))/

(SUM(C0UNT(F1 rstjame) )*SUM(COUNT(*)))

FROM Customers GROUP BY Fi rstjame:

Предположим, что при первом вычислении мы получим селективность, равную 0,0086, а при втором - 0,018. Далее предположим, что в нашей таблице 1 ООО ООО строк, а индекс указывает на 200 строк в каждом листовом блоке (меньше, чем обычно, так как у нас необычно широкий 1слюч индекса). Условие на Area Code определяет количество сканируемых блоков индекса, поэтому сначала найдем количество строк, на которые указывает условие. Наша формула выглядит как 0,0086 X 1 ООО ООО = 8 600, то есть база данных сканирует 43 (8 600/20) листовых блока. В запросах к одной таблице всегда можно пренебречь считыванием корневого блока и средних блоков. Вероятнее всего, эти 43 листовых блока хорошо кэшированы и для их считывания требуется около миллисекунды.

ПРИМЕЧАНИЕ

Базы данных способны выполнять приблизительно 60 ООО операций логического ввода-вывода на обычных процессорах. Однако ваши оценки производительности могут заметно отличаться. В этой книге я указываю такие числа, как 300 строк индекса в листовом блоке и 60 ООО операций логического ввода-вывода, так как они достаточно точны и удобны для интуитивного понимания приоритетов настройки. Среди множества производителей процессоров и серверов баз данных с разнообразными размерами блоков и столбцов эти числа могут легко измениться в четыре раза и даже более, а производительность, без сомнения, существенно возрастет через какое-то время после выхода этой книги. Интуитивное понимание и знание ло крайней мере порядка изменения этих чисел все же помогут вам, и, я надеюсь, вы считаете запоминание числа более легкой задачей, чем запоминание сложного условного диапазона.

8 600 операций считывания из таблицы могут стать проблемой, но, к счастью, у нас есть дополнительная селективность условия по столбцу Fi rstName, которая сокращает количество строк приблизительно до 155 (8 600 х 0,018). Для таблицы будет выполнено приблизительно 155 операций логического ввода-вывода и несколько операций физического ввода-вывода, так как коэффициент успешного попадания в кэш для таблицы хуже, чем для более компактного индекса.

Селективность фильтра для нескольких столбцов, 0,0086 х 0,018 = 0,000155, позволяет попасть в диапазон, подходящий для индексного доступа, хотя селективность только по первому столбцу находится в переходной зоне. Обратите вни-



1 ... 12 13 14 [ 15 ] 16 17 18 ... 107

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика