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

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


Чтобы подсчитать селективность условия Unpaid F1ag- У, начните с выполнения следующих двух запросов:

SELECT COUNT(*) FROM Orders WHERE Unpaid Flag-Y: SELECT COUNT(*) FROM Orders:

Селективность условия равна результату первого оператора, поделенному на результат второго.

Теперь рассмотрим запрос SELECT ... FROM OrderJetaHs WHERE Order ID-:1d:

Конечные пользователи будут запрашивать детальную информацию о заказах, разбросанных в таблице случайным образом. Это можно предположить даже с учетом того, что приложение заменяет параметр :id фактическим значением - ведь приложению нет смысла всегда обращаться к одному и тому же заказу. Запрос по любому идентификатору не может существовать сам по себе, он представляет целое семейство запросов, которое следует рассматривать и настраивать как единое целое. Конечные пользователи с одинаковой вероятностью могут обратиться к любому заказу, поэтому вычислять селективность фильтра следует так: SELECT 1 / COUNT(DISTINCT OrderJD) FROM Orderjetails;

Чуть более сложный случай возникает, когда конечный пользователь может обращаться к любому значению, но в действительности чаще обращается к каким-то более популярным значениям, чем к другим, менее востребованным. Например, если операторы ищут определенного покупателя путем выборки всех покупателей с искомой фамилией, то они чаще будут задавать поиск по распространенным фамилиям, чем по редким, используя, например, такой запрос: SELECT ... FROM Customers WHERE Lastjame - SMITH:

Если вы здесь подсчитаете различные имена так же, как ранее подсчитывались идентификаторы запросов, то получите сверхоптимистичную селективность, которая предполагает, что вероятность поиска по Last Nan)e-KMETEC такая же, как и по Last Nanie- SMITH. Для каждой фамилии селективность равна п (i) / С, где п (i) - количество строк с i-й отличной от нуля фамилией, а С - общее количество строк в таблице. Если бы вероятность выбора любой фамилии была одинакова, то можно было бы просто подсчитать среднее п( i) / С по всем фамилиям. Это среднее значение было бы одинаково для всех различных фамилий. Однако вероятность поиска фамилии в нашем сценарии равна n(i) / С, где С - количество строк с фамилиями, не равными null. Следовательно, нам требуется сумма селективно-стей, умноженных на вероятность появления каждой селективности, то есть сумма (n(i) / С) ? (n(i) / С) по всем фамилиям. Так как С - это также сумма отдельных значений п(1), можно подсчитать селективность фильтра на SQL следующим образом:

SELECT SUM(COUNT(LastName)*COUNT(Last Name))/ (SUM(COUNT(Last Name))*SUM(COUNT(*))) FROM Customers GROUP BY Lastjame:

Селективность условия на диапазоне индекса

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



и точка конца диапазона. Значением этих конечных точек может быть плюс или минус бесконечность, что означает, что диапазон может быть не ограничен на любом из концов, хотя обычно не на обоих. Диапазон может исключать любую или обе конечных точки в зависимости от природы граничного условия. Например, условие на диапазон (Sal агу > 4000 AND Sal ary < 8000) ис1слючает обе конечных точки граничными условиями неравенства.

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

ПРИМЕЧАНИЕ

Индексы, базирующиеся на функциях, которые поддерживает Oracle, - основное исключение из этого правила. Они позволяют отдельно индексировать результат применения к столбцам таблицы некоторого выражения (например, UPPER(Last Name)), чтобы использовать индексированный доступ к условиям по этому выражению, например, UPPER(Last Name) LIKE SMITH%.

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

Простой пример функции, делающей невозможным использование индекса, - сравнение выражений различных типов, для которого база данных неявно применяет функцию преобразования типов. Например, несовместимое по типу условие CharacterColumn = 94303 на самом деле превращается в Oracle в TO NUMBER(CharacterColumn) = 94303. Чтобы разрешить эту проблему и использовать индекс по символьному столбцу, выполните преобразование явно. Например:

Таблица 2.1. Соответствия преобразования Исходное выражение Чем заменить

aiaracterColumn=94303 CharacterColumn=94303

CharacterColumn=TRUNC(SYSDATE) CharacterColumn=TO CHAR(SYSDATE,DD-MON-YyYY)

ПРИМЕЧАНИЕ

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

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



ВНИМАНИЕ

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

Сервер баз данных обычно решает, что IndexedCol IS NULL определяет слишком большой диапазон значений, чтобы он мог быть полезным, и поэтому игнорирует такие условия при установлении конечных точек диапазона.

ПРИМЕЧАНИЕ

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

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

тивному индексированному соединению, если при этом внешний хслюч одного типа указывает на первичный ключ другого типа.

ВНИМАНИЕ -

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

При вычислении размера диапазона сканирования индекса можно применять несколько правил.

Условия на ведущий столбец рассматриваемого индекса подходят для выяснения начальной или конечной точки диапазона. Условия на остальные столбцы того же индекса не подходят для выяснения начальной или конечной точки диапазона, если только у вас нет точных условий равенства для всех упомянутых столбцов этого индекса. Например, индекс по (Date Col umn. ID Number), если применить его для условия Date Column >= TO DATE( 2003/01/01. YYYY/MM/DD), позволяет узнать диапазон сканирования, полностью определенный условием даты. Дальнейшие условия на второй столбец, например, ID Number=137, не сужают диапазон сканирования. Чтобы сузить диапазон, основываясь на втором условии, вам необходимо просмотреть длинный список диапазонов, по одному для каждого возможного значения DateCol umn, удовлетворяющего первому условию, но серверы баз данных не делают этого. Однако если вы поменяете местами столбцы в индексе, получив (ID Number, Date Co1umn), то эти же два условия совместно определят крайние точки диапазона, и сканирование полученного небольшого диапазона индекса будет выполнено быстрее.



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

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