На примере оптимизатора СУБД SQLBase рассмотрим основные принципы
Когда
Событие, которое обычно приводит к обновлению SQL UPDATE STATISTIC. Эта команда проверяет таблицы и индексы базы данных, вычисляет требуемые статистические показатели и затем сохраняет их в соответствующих таблицах системного каталога. Статистика также создается для индексов или таблиц при их первоначальном создании. Если никаких строк не вставляется в таблицы и индексы до момента обновления статистики по команде SQL UPDATE STATISTIC, то статистические показатели устанавливаются к значениям по умолчанию.
Как правило,
Статистика, связанная с таблицами базы данных, поддерживается в двух различных таблицах системного каталога, каждая из которых описывается ниже. Все колонки, не указанные специально как динамически поддерживаемые, являются статическими и заполняются при выполнении команд UPDATE STATISTIC или CREATE.
В таблице системного каталога SYSADM.SYSTABLES для сохранения статистики используются следующие колонки:
ROWCOUNT . Значение этой колонки есть число строк в таблице. Этот статистический показатель поддерживается динамически в странице управления таблицей (table's control page), и принимает конкретное значение при выполнении команды UPDATE STATISTIC.PAGECOUNT. Значением этой колонки является общее число страниц данных в таблице. Этот статистический показатель также поддерживается динамически, но принимает конкретное значение только когда команда UPDATE STATISTIC выполняется. Когда эта колонка поддерживается системой, она всегда будет суммой двух нижеследующих колонок ROWPAGECOUNT и LONGPAGECOUNT. Если ROWPAGECOUNT. Эта колонка содержит число основных станиц строк, занятых под таблицу, плюс число всех страниц расширения, которые могут быть распределены для таблицы. Этот динамический статистический показатель генерируется только по команде.LONGPAGECOUNT. Эта колонка содержит число страниц, распределенных таблице для колонок типа LONG VARCHAR. Этот динамический статистический показатель генерируется только по команде.EVENT_PAGECOUNT. Эта колонка содержит среднюю долю данных, сохраненных в основных станицах строк и страницах расширения. Это число не включает страницы для длинных строк.AVRROWLEN. Эта колонка содержит действительную среднюю длину строк в таблице. Это значение может значительно отличаться от заданной длины строки, так как СУБД SQLBase сохраняет все колонки как данные переменной длины, независимо от типа данных, используемого в определении колонок. Заметим, что эта длина строки является только длиной строки, сохраняемой в основной странице и странице расширения, и, следовательно, исключает все колонки типа LONG VARCHAR.AVRROWLONGLEN. Эта колонка содержит действительную среднюю длину всех колонок типа LONG VARCHAR, хранимых в таблице. Она будет содержать нуль, если переменных такого типа в таблице нет.В таблице системного каталога SYSADM.SYSCOLUMNS поддерживается следующая статистическая информация:
AVRCOLLEN. Эта колонка содержит действительную среднюю длину данной колонки для всех строк таблицы. Это значение может значительно отличаться от заданной при определении длины колонки, так как СУБД SQLBase сохраняет все колонки как данные переменной длины. Основная страница строки хранит описание длины данных для каждой непустой колонки.AVRCOLLONGLEN. Эта колонка содержит действительную длину колонки типа LONG VARCHAR для всех строк в таблице. Это значение равно нулю, если такие колонки отсутствуют в таблице.Статистика, связанная с индексами таблицы, также поддерживается в двух отдельных таблицах системного каталога. Все колонки (за исключением одной - HEIGTH - в таблице SYSINDEXES ) поддерживаются статически и заполняются, когда выполняется команда UPDATE STАTISTICS или создается индекс.
В таблице SYSADM.SYSINDEXES статистическая информация поддерживается в следующих колонках:
HEIGTH. Высота индексного дерева есть число узлов, которые нужно прочитать начиная с корневого уровня и заканчивая уровнем листьев включительно. Также она называется глубиной дерева (depth). Этот статистический показатель также поддерживается и динамически в странице управления индексами. Это поле равно нулю для хэш-индекса.LEAFCOUNT. Общее число узлов на нижнем уровне (число листьев) индекса равно значению, сохраняемому в этой колонке. Также это есть число страниц в подмножестве индексной последовательности. Равно нулю для хэш-индеса.CLUSTERCOUNT. Общее число изменений страниц, которое происходило бы, если вся таблица была прочитана через подмножество индексной последовательности. Для полностью PRIMPAGECOUNT. Число базовых страниц, которые были распределены основной таблице для размещения в хэш-индексе. Это есть число слотов хэширования доступных для распределения строк. Равно нулю для В+-индекса.OVFPAGECOUNT. Эта колонка содержит число страниц переполнения, которые распределены таблицы для размещения в хэш-индексе. Когда таблица и индекс первоначально создаются, это число отражает число страниц переполнения, которое предполагается распределить. Затем это число увеличивается, когда дополнительная страница переполнения требуется для разрешения коллизии при хэшировании. Это поле равно нулю для В+-индекса.AVRKEYLEN. Для В+ -индексов эта колонка содержит среднюю длину ключа для всех входов индекса. Это число необходимо для того, чтобы поддерживать все входы индекса как данные с переменной длиной. Это поле равно нулю для хэш-индексов.В таблице SYSADM.SYSKEYS поддерживается следующая статистическая информация.
DISTINCTCOUNT. Эта колонка содержит число различных ключей в индексе. Для каждой из существующих возможных комбинаций значений Простейший пример есть колонка Пол (SEX_CODE), которая имеет кардинальность 2. Рассмотрим следующий индекс:
CREATE INDEX XNKSALS ON EMPLOYEE (DEPT, SALARY, YEARS_SERVICE);
Таблица EMPLOYEE содержит 250 строк, по одному для каждого служащего компании. Кардинальность множества значений колонок есть:
При этих заданных условиях строки таблицы, которые описывают эти индексируемые колонки, имеют следующие значения DISTICTCOUNT:
DEPT 10, по одному для каждого отдела в компании.SALARY - 250. Так как каждый служащий имеет дискретное значение зарплаты, число ключей в этой точке индекса равно числу строк в таблице. Альтернативно, если существует только пять размеров зарплат, выплачиваемых компанией, и каждый отдел имеет кого-нибудь с этими пятью размерами зарплат, то DISTICTCOUNT равно 50 (=5*10).YEARS_SERVICE - 250. Так как поле зарплаты имеет уже кардинальность, равную числу строк в таблице, это поле не может превышать этого значения. Можно ожидать, что число входов индекса на каком-либо уровне может превысить число строк в таблице.Другими словами, если большинство строк таблицы должны быть выбраны, использование индекса повлечет за собой увеличение числа операций ввода/вывода за счет чтения индекса. При этом именно
Численно
Определение EMPLOYEE_NO=65, зависит от того, какой оператор используется в предикате. Оператор влияет на
Чем большее число строк отбрасывает оператор предиката при выборке (ограничивает), тем меньше DISTINCTCOUNT таблицы SYSADM.SYSINDEXES для этой колонки (как индексируемого ключа).
Однако непросто вычислить
ORDER_DATE > JAN-01-1900 ORDER_DATE > SYSDATE -1 DAY
Очевидно, что первый предикат, как можно было бы ожидать, возвратит гораздо больше строк, чем второй, когда будет применен к таблице ORDER.
Как оптимизатор может определить это? Оказывается, что оптимизатор вычисляет ORDER_DATE ). Затем он оценивает число строк, которое удовлетворяет предикату, экстраполируя пропорцию индексных ключей на этом уровне индекса. Этот метод, называемый сканирование B-дерева (B-tree
Другой фактор, который играет роль в определении DISTINCTCOUNT в предположении равновероятного распределения значений колонки по строкам таблицы. Такое предположение позволяет оптимизатору быть нечувствительным к действительным значениям операнда с другой стороны знака равенства. Однако для использования метода сканирования В-дерева оптимизатор должен быть способным найти значение другого операнда. Когда операнд является
Нижеследующая таблица 16.1 суммирует определения
| Тип предиката впорядке приоритета | Константа | Не константа |
|---|---|---|
| = | 1/card | 1/card |
| !=,<> | 1-1/card | 1/3 |
| > | Сканирование индекса | 1/3 |
| !> | Сканирование индекса | 1/3 |
| < | Сканирование индекса | 1/3 |
| >= | Сканирование индекса | 1/3 |
| <= | Сканирование индекса | 1/3 |
Between |
Сканирование индекса | 1/3 |
Null |
- | Не используется |
Exists |
Преобразование | Преобразование |
Like |
Сканирование индекса | Не определен |
In |
Преобразование | Преобразование |
Когда несколько предикатов используются для выборки строк из одной таблицы, оптимизатор следует некоторым фиксированным правилам, которые комбинируют
Пример. Пусть задан предикат EMPLOYEE_NO = 45 AND DEPT = 50 AND SALARY > 25000.
Предположим, что индекс определен для EMPLOYEE_NO, DEPT, SALARY. Комбинация факторов
Пример. Пусть задан предикат SALARY > 25000 AND DEPT = 50 AND YEARS_SERVICE > 3.
Предположим, что индекс определен для SALARY, DEPT, YEARS_SERVICE. Оптимизатор определяет
Таким образом, на первом шаге своей работы оптимизатор СУБД SQLBase, подготавливая для выполнения команду SQL, строит список вариантов
Далее
При создании
Существует много вариантов увеличения производительности запросов. Основной идеей для выбора самого подходящего является построение запроса таким образом, чтобы
Так, например, при работе с оптимизатором СУБД SQLBase для увеличения производительности конкретной команды SELECT, проектировщик базы данных или
Обновление статистики. Статистика в СУБД SQLBase поддерживается независимо как для таблиц, так и для индексов. Оптимизатор использует эти статистики для вычисления стоимости различных
Оптимальное множество индексов. Другим аспектом работы с GROUP BY и ORDER BY. Если утверждение SELECT выполняется медленно, то это, вероятно, либо соединение, сортировка, либо чтение большой таблицы. Индексы могут увеличить производительность всех этих операций.
Общая стратегия индексирования состоит в WHERE, GROUP BY, ORDER BY. Этот первоначальный набор индексов базы данных обеспечивает индексацию для выполнения SELECT
С другой стороны, первоначальный набор индексов может не удовлетворять требованиям по производительности для всех запросов. Например, некоторые запросы, содержащие колонки соединения, не являющиеся ни первичным, ни внешним ключами, могут выполняться медленно. Для таких запросов, чтобы они удовлетворяли критериям производительности, необходимо добавить дополнительные индексы. Однако нецелесообразно создавать один или более индексов для каждого оператора выборки, поскольку:
DML ;Следовательно, общая цель проектирования состоит в том, чтобы создать набор индексов, который отвечает требованиям производительности для всех транзакций к базе данных. Это и есть оптимальный набор индексов.
Переписывание SELECT. Она может быть применена в при использовании других реляционных СУБД.
Однако в некоторых СУБД, например СУБД Oracle, проектировщик базы данных может явно влиять на выбор тех или иных вариантов улучшения скорости выполнения запросов.
Для управления оптимизатором СУБД Oracle используются специальные подсказки, которые записываются в SQL-командах. Такие подсказки влияют на выбор конкретного способа обращения к данным. Пример ниже содержит подсказку оптимизатора для использования индекса (в предположении, что таблица имеет один индекс):
Пример SELECT /* + index */ EMPLOYEE_NO, DEPT, SALARY FROM EMPLOYEE WHERE EMPLOYEE_NO = 65;
Подсказка является частью комментария, следующего за ключевым словом команды, и отмечается символом "+".
Для эффективного переписывания
Одним из важных вопросов при работе с
ALTER SESSION SET OPTIMIZER_GOAL = <режим>;
В качестве режима может быть задано одно из следующих значений:
| Подсказка | Описание |
|---|---|
ROWID |
Использование идентификатора |
CLUSTER |
Сканирование ключа кластера |
HASH |
Сканирование хэш-индекса |
INDEX |
Сканирование индекса |
INDEX_ASC |
Сканирование индекса в порядке возрастания |
INDEX_DECS |
Сканирование индекса в порядке убывания |
AND_FFS |
Быстрое полное сканирование индекса |
AND_EQUAL |
Использование нескольких индексов со слиянием результатов |
FULL |
Полное сканирование таблицы |
FIRST_ROWS - это значение задает минимизацию времени отклика, т.е. сведение к минимуму временного интервала от начала выполнения запроса и до возвращения первой строки результата в приложение;ALL_ROWS - это значение задает использование оптимизации, основанной на вычислении стоимости, для минимизации общего количества строк, обрабатываемых системой в единицу времени (число транзакций в секунду).Более подробно об использовании оптимизатора запросов СУБД Oracle можно прочитать в рекомендованной к лекции литературе.
Рассмотрим теперь общую
Шаг 1. Обновить статистику. До того как добавить индексы, необходимо убедиться, что UPDATE STSTISTICS (для SQLBаse) или другую специальную команду СУБД. С другой стороны, если вы используете небольшую тестовую базу данных, то можно вручную вычислить необходимые статистические показатели и внести их в системный каталог.
Когда вы обновляете статистику, вам следовало бы скомпилировать команду SQL, установив параметр PLANONLY в положение ON. Сравните новый план запроса со старым до обновления статистики, для того чтобы определить изменения в нем (иногда требуется довольно длительное время для построения плана). Сравнивая планы, можно избежать повторного выполнения запроса только для того, чтобы убедиться, что производительность его выполнения идентична предыдущему выполнению этого запроса. Если статистика изменилась, то выполните запрос, чтобы определить, увеличилась ли производительность и насколько.
Шаг 2. Упростить команду SELECT. Перед добавлением индексов или переписыванием SELECT как можно проще, сократив по мере возможности число переменных в нем. Упростив запрос, скомпилируйте команду, чтобы посмотреть план запроса. Сравните новый план запроса со старым. Определите, увеличилась ли производительность запроса, выполнив его.
Для того чтобы упростить SELECT, необходимо:
Исключение ненужных предикатов и предложений. Обычно в команду SELECT включают предложений больше, чем это необходимо на самом деле. Так делается для того, чтобы гарантировать корректность ответа, или из-за плохого понимания синтаксиса SQL. До попытки настроить запрос проектировщик базы данных должен удалить все ненужные предложения и предикаты.
Примерами предложений, которые обычно включаются в запрос, но не являются необходимыми, являются следующие:
ORDER BY. Часто это предложение включается, даже если определенный порядок в результирующем множестве не требуется приложением или конечным пользователем.WHERE. Часто это предложение содержит избыточное WHERE являются избыточными, так как DEPT_NO есть первичный ключ и, следовательно, будет уникально идентифицировать только одну строку:WHERE DEPT_NO = 10 AND DEPT_NAME = 'PERATIONS'.
Расстановка скобок в арифметических и логических выражениях. Синтаксис SQL SQLBase включает специальные правила предшествования для оценки арифметических и логических выражений. Однако достаточно просто сделать ошибку при применении правил предшествования. Следовательно, мы рекомендуем вам расставлять скобки в этих выражениях для явного определения предшествования в выполнении операций. Вы можете подумать, что оптимизатор оценивает выражения одним способом, а в действительности он поступает по-другому.
Преобразование
Следовательно, при настройке запроса следует преобразовать все
При использовании
Рассмотрим следующий пример. Предикаты: Amount > :BindVar и Amount > 1000. Преимущество использования первого предиката состоит в том, что команда может быть откомпилирована один раз и затем много раз использована с различными значениями. Недостаток состоит в том, что
С другой стороны, во втором предикате оптимизатор знает сравниваемое значение и во время компиляции, и во время выполнения и, следовательно, способен более точно вычислить
LIKE. Этот оператор может включать символ подстановки.
Пример. Рассмотрим запрос на поиск всех продавцов, чье имя начинается с буквы "А": SELECT * FROM CUSTOMER WHERE NAME LIKE 'A%';
Символ подстановки может стоять и в начале, и в середине, и в конце строки шаблона. Природа индексной структуры на основе В-дерева такова, что она может работать с символом подстановки, если он не стоит в начальной позиции строки. Ясно, что оптимизатор не будет использовать индекс, если символ постановки будет стоять на первой позиции (как при использовании LIKE ). В этих случаях будет применено сканирование таблицы.
Преобразовывайте LIKE в константы для увеличения производительности такого запроса.
Шаг 3. Пересмотреть план запроса. Выполните запрос так, чтобы посмотреть его план. Вы должны хорошо понимать план запроса, чтобы использовать его. Несколько элементов этого плана требуют особого внимания.
SELECT, так, чтобы соединения использовали метод слияния индексов. Иногда хэш-соединение может представлять более лучший метод соединения, когда большое количество данных обрабатывается.Шаг 4. Локализовать узкие места. Запрос, который выполняется медленно, может содержать много предложений и предикатов. Если это так, нужно определить, какие предложения или предикаты приводят к плохой производительности. Если удалить одно или два предложения или предиката, производительность выполнения запроса возрастает значительно. Эти предложения являются критическими параметрами выполнения запроса.
Можно поэкспериментировать с запросом, поочередно удаляя из него предложения или предикаты до тех пор, пока не будет достигнут подходящий уровень производительности. Локализуйте критические предложения и предикаты.
Примеры:
Если запрос содержит предложение ORDER BY, закомментируйте его и посмотрите, изменится ли план этого запроса. Если план изменился, выполните запрос для того, чтобы определить, увеличилась ли производительность.Если запрос содержит несколько соединений, локализуйте то, которое замедляет выполнение. Комментируйте последовательно все соединения, кроме одного, и выполняйте запрос. Определите, какое соединение самое критичное.
Исключите любые АТ-функции (@), выполняющиеся в WHERE, и посмотрите, не выросла ли производительность. Может быть, индекс не используется из-за применения функции. В этом случае можно построить индекс с использованием этой функции.
Шаг 5. Создать индексы для одной колонки для критических параметров. Если завершены шаги 1-4 и запрос еще не удовлетворяет требованиям производительности, можно попытаться создать индексы специально для этого запроса, чтобы увеличить его производительность. В общем, индексы для одной колонки предпочтительнее, чем составные индексы, так как более вероятно их использование в других запросах. Попытайтесь увеличить производительность запроса с индексом для одной колонки, прежде чем разрабатывать многоколоночные индексы.
Локализуйте следующие колонки таблицы из запроса, которые не имеют индекса:
GROUP BY. Если предложение GROUP BY содержит более чем одну колонку, необходим составной индекс для увеличения производительности этого GROUP BY предложения. Опустите создание этих колонок до шага 6.ORDER BY. Если предложение ORDER BY содержит более чем одну колонку, необходим составной индекс для увеличения производительности этого ORDER BY предложения. Опустите создание этих колонок до шага 6.FROM.Сравните эти колонки с критическими факторами, определенными на шаге 4. Каждая из колонок, идентифицированная выше, должна соответствовать одному из критических предложений или предикатов, определенных на шаге 4. Если это так, создайте индекс для каждой из этих колонок. Определите, будет ли добавление этих индексов изменять план запроса. Если изменения будут иметь место, выполните запрос для того, чтобы определить, увеличилась ли производительность после добавления этих индексов.
Если добавление индексов не увеличивает производительность значительно, создайте другие индексы для других колонок из списка критических. Если не удается увеличить производительность запроса за счет создания индексов для одной колонки, то перейдите к следующему шагу.
Шаг 6. Создать индексы для нескольких колонок. Процедура идентификации колонок для создания составных индексов состоит в следующем:
Типы составных индексов приведены ниже.
GROUP BY. Если предложение GROUP BY содержит более чем одну колонку, создайте индекс для всех этих колонок. Специфицируйте колонки в том же порядке, как они указаны в предложении.ORDER BY. Если предложение ORDER BY содержит более чем одну колонку, создайте индекс для всех этих колонок. Специфицируйте колонки в том же порядке, как они указаны в предложении. Также не забудьте указать последовательность сортировки для индекса.FROM, которая имеет по крайней мере один предикат в предложении WHERE, создайте составной индекс для колонок соединения и колонки из ограничивающего предиката с низким FROM, которая имеет по крайней мере один предикат в предложении WHERE, создайте составной индекс для колонок соединения и всех колонок из всех предикатов. Порядок колонок в индексе является критическим для оптимизатора. Колонки из предикатов равенства следует размещать ранее всех других колонок в порядке возрастания Шаг 7. Удалить все индексы, которые не используются в плане запроса. Как уже указывалось выше, индексы замедляют выполнение команд , а их сопровождение требует времени и увеличивает стоимость обработки. Следовательно, вам следует проследить использование всех созданных индексов и удалить те, которые не используются запросом.
На примере оптимизатора СУБД SQLBase рассмотрим основные принципы
Когда
Событие, которое обычно приводит к обновлению SQL UPDATE STATISTIC. Эта команда проверяет таблицы и индексы базы данных, вычисляет требуемые статистические показатели и затем сохраняет их в соответствующих таблицах системного каталога. Статистика также создается для индексов или таблиц при их первоначальном создании. Если никаких строк не вставляется в таблицы и индексы до момента обновления статистики по команде SQL UPDATE STATISTIC, то статистические показатели устанавливаются к значениям по умолчанию.
Как правило,
Статистика, связанная с таблицами базы данных, поддерживается в двух различных таблицах системного каталога, каждая из которых описывается ниже. Все колонки, не указанные специально как динамически поддерживаемые, являются статическими и заполняются при выполнении команд UPDATE STATISTIC или CREATE.
В таблице системного каталога SYSADM.SYSTABLES для сохранения статистики используются следующие колонки:
ROWCOUNT . Значение этой колонки есть число строк в таблице. Этот статистический показатель поддерживается динамически в странице управления таблицей (table's control page), и принимает конкретное значение при выполнении команды UPDATE STATISTIC.PAGECOUNT. Значением этой колонки является общее число страниц данных в таблице. Этот статистический показатель также поддерживается динамически, но принимает конкретное значение только когда команда UPDATE STATISTIC выполняется. Когда эта колонка поддерживается системой, она всегда будет суммой двух нижеследующих колонок ROWPAGECOUNT и LONGPAGECOUNT. Если ROWPAGECOUNT. Эта колонка содержит число основных станиц строк, занятых под таблицу, плюс число всех страниц расширения, которые могут быть распределены для таблицы. Этот динамический статистический показатель генерируется только по команде.LONGPAGECOUNT. Эта колонка содержит число страниц, распределенных таблице для колонок типа LONG VARCHAR. Этот динамический статистический показатель генерируется только по команде.EVENT_PAGECOUNT. Эта колонка содержит среднюю долю данных, сохраненных в основных станицах строк и страницах расширения. Это число не включает страницы для длинных строк.AVRROWLEN. Эта колонка содержит действительную среднюю длину строк в таблице. Это значение может значительно отличаться от заданной длины строки, так как СУБД SQLBase сохраняет все колонки как данные переменной длины, независимо от типа данных, используемого в определении колонок. Заметим, что эта длина строки является только длиной строки, сохраняемой в основной странице и странице расширения, и, следовательно, исключает все колонки типа LONG VARCHAR.AVRROWLONGLEN. Эта колонка содержит действительную среднюю длину всех колонок типа LONG VARCHAR, хранимых в таблице. Она будет содержать нуль, если переменных такого типа в таблице нет.В таблице системного каталога SYSADM.SYSCOLUMNS поддерживается следующая статистическая информация:
AVRCOLLEN. Эта колонка содержит действительную среднюю длину данной колонки для всех строк таблицы. Это значение может значительно отличаться от заданной при определении длины колонки, так как СУБД SQLBase сохраняет все колонки как данные переменной длины. Основная страница строки хранит описание длины данных для каждой непустой колонки.AVRCOLLONGLEN. Эта колонка содержит действительную длину колонки типа LONG VARCHAR для всех строк в таблице. Это значение равно нулю, если такие колонки отсутствуют в таблице.Статистика, связанная с индексами таблицы, также поддерживается в двух отдельных таблицах системного каталога. Все колонки (за исключением одной - HEIGTH - в таблице SYSINDEXES ) поддерживаются статически и заполняются, когда выполняется команда UPDATE STАTISTICS или создается индекс.
В таблице SYSADM.SYSINDEXES статистическая информация поддерживается в следующих колонках:
HEIGTH. Высота индексного дерева есть число узлов, которые нужно прочитать начиная с корневого уровня и заканчивая уровнем листьев включительно. Также она называется глубиной дерева (depth). Этот статистический показатель также поддерживается и динамически в странице управления индексами. Это поле равно нулю для хэш-индекса.LEAFCOUNT. Общее число узлов на нижнем уровне (число листьев) индекса равно значению, сохраняемому в этой колонке. Также это есть число страниц в подмножестве индексной последовательности. Равно нулю для хэш-индеса.CLUSTERCOUNT. Общее число изменений страниц, которое происходило бы, если вся таблица была прочитана через подмножество индексной последовательности. Для полностью PRIMPAGECOUNT. Число базовых страниц, которые были распределены основной таблице для размещения в хэш-индексе. Это есть число слотов хэширования доступных для распределения строк. Равно нулю для В+-индекса.OVFPAGECOUNT. Эта колонка содержит число страниц переполнения, которые распределены таблицы для размещения в хэш-индексе. Когда таблица и индекс первоначально создаются, это число отражает число страниц переполнения, которое предполагается распределить. Затем это число увеличивается, когда дополнительная страница переполнения требуется для разрешения коллизии при хэшировании. Это поле равно нулю для В+-индекса.AVRKEYLEN. Для В+ -индексов эта колонка содержит среднюю длину ключа для всех входов индекса. Это число необходимо для того, чтобы поддерживать все входы индекса как данные с переменной длиной. Это поле равно нулю для хэш-индексов.В таблице SYSADM.SYSKEYS поддерживается следующая статистическая информация.
DISTINCTCOUNT. Эта колонка содержит число различных ключей в индексе. Для каждой из существующих возможных комбинаций значений Простейший пример есть колонка Пол (SEX_CODE), которая имеет кардинальность 2. Рассмотрим следующий индекс:
CREATE INDEX XNKSALS ON EMPLOYEE (DEPT, SALARY, YEARS_SERVICE);
Таблица EMPLOYEE содержит 250 строк, по одному для каждого служащего компании. Кардинальность множества значений колонок есть:
При этих заданных условиях строки таблицы, которые описывают эти индексируемые колонки, имеют следующие значения DISTICTCOUNT:
DEPT 10, по одному для каждого отдела в компании.SALARY - 250. Так как каждый служащий имеет дискретное значение зарплаты, число ключей в этой точке индекса равно числу строк в таблице. Альтернативно, если существует только пять размеров зарплат, выплачиваемых компанией, и каждый отдел имеет кого-нибудь с этими пятью размерами зарплат, то DISTICTCOUNT равно 50 (=5*10).YEARS_SERVICE - 250. Так как поле зарплаты имеет уже кардинальность, равную числу строк в таблице, это поле не может превышать этого значения. Можно ожидать, что число входов индекса на каком-либо уровне может превысить число строк в таблице.Другими словами, если большинство строк таблицы должны быть выбраны, использование индекса повлечет за собой увеличение числа операций ввода/вывода за счет чтения индекса. При этом именно
Численно
Определение EMPLOYEE_NO=65, зависит от того, какой оператор используется в предикате. Оператор влияет на
Чем большее число строк отбрасывает оператор предиката при выборке (ограничивает), тем меньше DISTINCTCOUNT таблицы SYSADM.SYSINDEXES для этой колонки (как индексируемого ключа).
Однако непросто вычислить
ORDER_DATE > JAN-01-1900 ORDER_DATE > SYSDATE -1 DAY
Очевидно, что первый предикат, как можно было бы ожидать, возвратит гораздо больше строк, чем второй, когда будет применен к таблице ORDER.
Как оптимизатор может определить это? Оказывается, что оптимизатор вычисляет ORDER_DATE ). Затем он оценивает число строк, которое удовлетворяет предикату, экстраполируя пропорцию индексных ключей на этом уровне индекса. Этот метод, называемый сканирование B-дерева (B-tree
Другой фактор, который играет роль в определении DISTINCTCOUNT в предположении равновероятного распределения значений колонки по строкам таблицы. Такое предположение позволяет оптимизатору быть нечувствительным к действительным значениям операнда с другой стороны знака равенства. Однако для использования метода сканирования В-дерева оптимизатор должен быть способным найти значение другого операнда. Когда операнд является
Нижеследующая таблица 16.1 суммирует определения
| Тип предиката впорядке приоритета | Константа | Не константа |
|---|---|---|
| = | 1/card | 1/card |
| !=,<> | 1-1/card | 1/3 |
| > | Сканирование индекса | 1/3 |
| !> | Сканирование индекса | 1/3 |
| < | Сканирование индекса | 1/3 |
| >= | Сканирование индекса | 1/3 |
| <= | Сканирование индекса | 1/3 |
Between |
Сканирование индекса | 1/3 |
Null |
- | Не используется |
Exists |
Преобразование | Преобразование |
Like |
Сканирование индекса | Не определен |
In |
Преобразование | Преобразование |
Когда несколько предикатов используются для выборки строк из одной таблицы, оптимизатор следует некоторым фиксированным правилам, которые комбинируют
Пример. Пусть задан предикат EMPLOYEE_NO = 45 AND DEPT = 50 AND SALARY > 25000.
Предположим, что индекс определен для EMPLOYEE_NO, DEPT, SALARY. Комбинация факторов
Пример. Пусть задан предикат SALARY > 25000 AND DEPT = 50 AND YEARS_SERVICE > 3.
Предположим, что индекс определен для SALARY, DEPT, YEARS_SERVICE. Оптимизатор определяет
Таким образом, на первом шаге своей работы оптимизатор СУБД SQLBase, подготавливая для выполнения команду SQL, строит список вариантов
Далее
При создании
Существует много вариантов увеличения производительности запросов. Основной идеей для выбора самого подходящего является построение запроса таким образом, чтобы
Так, например, при работе с оптимизатором СУБД SQLBase для увеличения производительности конкретной команды SELECT, проектировщик базы данных или
Обновление статистики. Статистика в СУБД SQLBase поддерживается независимо как для таблиц, так и для индексов. Оптимизатор использует эти статистики для вычисления стоимости различных
Оптимальное множество индексов. Другим аспектом работы с GROUP BY и ORDER BY. Если утверждение SELECT выполняется медленно, то это, вероятно, либо соединение, сортировка, либо чтение большой таблицы. Индексы могут увеличить производительность всех этих операций.
Общая стратегия индексирования состоит в WHERE, GROUP BY, ORDER BY. Этот первоначальный набор индексов базы данных обеспечивает индексацию для выполнения SELECT
С другой стороны, первоначальный набор индексов может не удовлетворять требованиям по производительности для всех запросов. Например, некоторые запросы, содержащие колонки соединения, не являющиеся ни первичным, ни внешним ключами, могут выполняться медленно. Для таких запросов, чтобы они удовлетворяли критериям производительности, необходимо добавить дополнительные индексы. Однако нецелесообразно создавать один или более индексов для каждого оператора выборки, поскольку:
DML ;Следовательно, общая цель проектирования состоит в том, чтобы создать набор индексов, который отвечает требованиям производительности для всех транзакций к базе данных. Это и есть оптимальный набор индексов.
Переписывание SELECT. Она может быть применена в при использовании других реляционных СУБД.
Однако в некоторых СУБД, например СУБД Oracle, проектировщик базы данных может явно влиять на выбор тех или иных вариантов улучшения скорости выполнения запросов.
Для управления оптимизатором СУБД Oracle используются специальные подсказки, которые записываются в SQL-командах. Такие подсказки влияют на выбор конкретного способа обращения к данным. Пример ниже содержит подсказку оптимизатора для использования индекса (в предположении, что таблица имеет один индекс):
Пример SELECT /* + index */ EMPLOYEE_NO, DEPT, SALARY FROM EMPLOYEE WHERE EMPLOYEE_NO = 65;
Подсказка является частью комментария, следующего за ключевым словом команды, и отмечается символом "+".
Для эффективного переписывания
Одним из важных вопросов при работе с
ALTER SESSION SET OPTIMIZER_GOAL = <режим>;
В качестве режима может быть задано одно из следующих значений:
| Подсказка | Описание |
|---|---|
ROWID |
Использование идентификатора |
CLUSTER |
Сканирование ключа кластера |
HASH |
Сканирование хэш-индекса |
INDEX |
Сканирование индекса |
INDEX_ASC |
Сканирование индекса в порядке возрастания |
INDEX_DECS |
Сканирование индекса в порядке убывания |
AND_FFS |
Быстрое полное сканирование индекса |
AND_EQUAL |
Использование нескольких индексов со слиянием результатов |
FULL |
Полное сканирование таблицы |
FIRST_ROWS - это значение задает минимизацию времени отклика, т.е. сведение к минимуму временного интервала от начала выполнения запроса и до возвращения первой строки результата в приложение;ALL_ROWS - это значение задает использование оптимизации, основанной на вычислении стоимости, для минимизации общего количества строк, обрабатываемых системой в единицу времени (число транзакций в секунду).Более подробно об использовании оптимизатора запросов СУБД Oracle можно прочитать в рекомендованной к лекции литературе.
Рассмотрим теперь общую
Шаг 1. Обновить статистику. До того как добавить индексы, необходимо убедиться, что UPDATE STSTISTICS (для SQLBаse) или другую специальную команду СУБД. С другой стороны, если вы используете небольшую тестовую базу данных, то можно вручную вычислить необходимые статистические показатели и внести их в системный каталог.
Когда вы обновляете статистику, вам следовало бы скомпилировать команду SQL, установив параметр PLANONLY в положение ON. Сравните новый план запроса со старым до обновления статистики, для того чтобы определить изменения в нем (иногда требуется довольно длительное время для построения плана). Сравнивая планы, можно избежать повторного выполнения запроса только для того, чтобы убедиться, что производительность его выполнения идентична предыдущему выполнению этого запроса. Если статистика изменилась, то выполните запрос, чтобы определить, увеличилась ли производительность и насколько.
Шаг 2. Упростить команду SELECT. Перед добавлением индексов или переписыванием SELECT как можно проще, сократив по мере возможности число переменных в нем. Упростив запрос, скомпилируйте команду, чтобы посмотреть план запроса. Сравните новый план запроса со старым. Определите, увеличилась ли производительность запроса, выполнив его.
Для того чтобы упростить SELECT, необходимо:
Исключение ненужных предикатов и предложений. Обычно в команду SELECT включают предложений больше, чем это необходимо на самом деле. Так делается для того, чтобы гарантировать корректность ответа, или из-за плохого понимания синтаксиса SQL. До попытки настроить запрос проектировщик базы данных должен удалить все ненужные предложения и предикаты.
Примерами предложений, которые обычно включаются в запрос, но не являются необходимыми, являются следующие:
ORDER BY. Часто это предложение включается, даже если определенный порядок в результирующем множестве не требуется приложением или конечным пользователем.WHERE. Часто это предложение содержит избыточное WHERE являются избыточными, так как DEPT_NO есть первичный ключ и, следовательно, будет уникально идентифицировать только одну строку:WHERE DEPT_NO = 10 AND DEPT_NAME = 'PERATIONS'.
Расстановка скобок в арифметических и логических выражениях. Синтаксис SQL SQLBase включает специальные правила предшествования для оценки арифметических и логических выражений. Однако достаточно просто сделать ошибку при применении правил предшествования. Следовательно, мы рекомендуем вам расставлять скобки в этих выражениях для явного определения предшествования в выполнении операций. Вы можете подумать, что оптимизатор оценивает выражения одним способом, а в действительности он поступает по-другому.
Преобразование
Следовательно, при настройке запроса следует преобразовать все
При использовании
Рассмотрим следующий пример. Предикаты: Amount > :BindVar и Amount > 1000. Преимущество использования первого предиката состоит в том, что команда может быть откомпилирована один раз и затем много раз использована с различными значениями. Недостаток состоит в том, что
С другой стороны, во втором предикате оптимизатор знает сравниваемое значение и во время компиляции, и во время выполнения и, следовательно, способен более точно вычислить
LIKE. Этот оператор может включать символ подстановки.
Пример. Рассмотрим запрос на поиск всех продавцов, чье имя начинается с буквы "А": SELECT * FROM CUSTOMER WHERE NAME LIKE 'A%';
Символ подстановки может стоять и в начале, и в середине, и в конце строки шаблона. Природа индексной структуры на основе В-дерева такова, что она может работать с символом подстановки, если он не стоит в начальной позиции строки. Ясно, что оптимизатор не будет использовать индекс, если символ постановки будет стоять на первой позиции (как при использовании LIKE ). В этих случаях будет применено сканирование таблицы.
Преобразовывайте LIKE в константы для увеличения производительности такого запроса.
Шаг 3. Пересмотреть план запроса. Выполните запрос так, чтобы посмотреть его план. Вы должны хорошо понимать план запроса, чтобы использовать его. Несколько элементов этого плана требуют особого внимания.
SELECT, так, чтобы соединения использовали метод слияния индексов. Иногда хэш-соединение может представлять более лучший метод соединения, когда большое количество данных обрабатывается.Шаг 4. Локализовать узкие места. Запрос, который выполняется медленно, может содержать много предложений и предикатов. Если это так, нужно определить, какие предложения или предикаты приводят к плохой производительности. Если удалить одно или два предложения или предиката, производительность выполнения запроса возрастает значительно. Эти предложения являются критическими параметрами выполнения запроса.
Можно поэкспериментировать с запросом, поочередно удаляя из него предложения или предикаты до тех пор, пока не будет достигнут подходящий уровень производительности. Локализуйте критические предложения и предикаты.
Примеры:
Если запрос содержит предложение ORDER BY, закомментируйте его и посмотрите, изменится ли план этого запроса. Если план изменился, выполните запрос для того, чтобы определить, увеличилась ли производительность.Если запрос содержит несколько соединений, локализуйте то, которое замедляет выполнение. Комментируйте последовательно все соединения, кроме одного, и выполняйте запрос. Определите, какое соединение самое критичное.
Исключите любые АТ-функции (@), выполняющиеся в WHERE, и посмотрите, не выросла ли производительность. Может быть, индекс не используется из-за применения функции. В этом случае можно построить индекс с использованием этой функции.
Шаг 5. Создать индексы для одной колонки для критических параметров. Если завершены шаги 1-4 и запрос еще не удовлетворяет требованиям производительности, можно попытаться создать индексы специально для этого запроса, чтобы увеличить его производительность. В общем, индексы для одной колонки предпочтительнее, чем составные индексы, так как более вероятно их использование в других запросах. Попытайтесь увеличить производительность запроса с индексом для одной колонки, прежде чем разрабатывать многоколоночные индексы.
Локализуйте следующие колонки таблицы из запроса, которые не имеют индекса:
GROUP BY. Если предложение GROUP BY содержит более чем одну колонку, необходим составной индекс для увеличения производительности этого GROUP BY предложения. Опустите создание этих колонок до шага 6.ORDER BY. Если предложение ORDER BY содержит более чем одну колонку, необходим составной индекс для увеличения производительности этого ORDER BY предложения. Опустите создание этих колонок до шага 6.FROM.Сравните эти колонки с критическими факторами, определенными на шаге 4. Каждая из колонок, идентифицированная выше, должна соответствовать одному из критических предложений или предикатов, определенных на шаге 4. Если это так, создайте индекс для каждой из этих колонок. Определите, будет ли добавление этих индексов изменять план запроса. Если изменения будут иметь место, выполните запрос для того, чтобы определить, увеличилась ли производительность после добавления этих индексов.
Если добавление индексов не увеличивает производительность значительно, создайте другие индексы для других колонок из списка критических. Если не удается увеличить производительность запроса за счет создания индексов для одной колонки, то перейдите к следующему шагу.
Шаг 6. Создать индексы для нескольких колонок. Процедура идентификации колонок для создания составных индексов состоит в следующем:
Типы составных индексов приведены ниже.
GROUP BY. Если предложение GROUP BY содержит более чем одну колонку, создайте индекс для всех этих колонок. Специфицируйте колонки в том же порядке, как они указаны в предложении.ORDER BY. Если предложение ORDER BY содержит более чем одну колонку, создайте индекс для всех этих колонок. Специфицируйте колонки в том же порядке, как они указаны в предложении. Также не забудьте указать последовательность сортировки для индекса.FROM, которая имеет по крайней мере один предикат в предложении WHERE, создайте составной индекс для колонок соединения и колонки из ограничивающего предиката с низким FROM, которая имеет по крайней мере один предикат в предложении WHERE, создайте составной индекс для колонок соединения и всех колонок из всех предикатов. Порядок колонок в индексе является критическим для оптимизатора. Колонки из предикатов равенства следует размещать ранее всех других колонок в порядке возрастания Шаг 7. Удалить все индексы, которые не используются в плане запроса. Как уже указывалось выше, индексы замедляют выполнение команд , а их сопровождение требует времени и увеличивает стоимость обработки. Следовательно, вам следует проследить использование всех созданных индексов и удалить те, которые не используются запросом.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.