|
Программирование >> Полное сканирование таблицы
просы, содержащие новые типы объектов, такие как растровые индексы, СВО. (Подробнее о том, какие функции не обрабатывает RBO, в следующем разделе, Управление выбором оптимизатора в Oracle .) Но, с другой стороны, RBO выполняет свою работу на удивление хорошо. Его эвристические функции прекрасно справляются с выбором наилучшего плана, обладая лишь небольшим объемом информации. В главе 6 я опишу свойства плана, который я называю надежным, плана, который хорошо работает на самых различных распределениях данных. RBO практически всегда выдает надежный план, если есть все необходимые индексы и разработчик не запретил использование индекса каким-либо из способов, рассмотренных ранее в этой главе. Имея правильные индексы, вы практически всегда можете получить наилучший план с любым из оптимизаторов, дополнив его ручной настройкой. При автоматизированной настройке самое большое преимущество СВО - его изобретательность, которую он проявляет даже с не идеальным индексированием и не оптимальным SQL. Чаще всего он выдает, по крайней мере, адекватный план, даже без ручной настройки. Когда возможно появление нескольких надежных планов, СВО с большей вероятностью найдет наилучший надежный план, а RBO выберет один из них, не зная относительной стоимости, если только вы не настроите SQL вручную. Управление выбором оптимизатора в Oracle Невозможно одновременно оптимизировать запросы Oracle для синтаксического и стоимостного оптимизаторов. Поэтому вы должны понимать, какими факторами руководствуется Oracle при выборе оптимизатора, и контролировать эти факторы, заставляя выбрать нужный оптимизатор. RBO не может обрабатывать объекты определенных типов и свойства объектов, которые еще не существовали на момент, когда Oracle заморозила код RBO. Однако вместо того, чтобы просто выдавать сообщение об ошибке, Oracle модифицировала код RBO, чтобы оптимизатор умел распознавать недопустимые для него случаи и передавать их СВО. Так, даже если вы думаете, что заставили систему использовать синтаксическую оптимизацию, в следующих ситуациях абсолютно точно будет использоваться стоимостная оптимизация. Существуют растровые индексы по любому столбцу таблицы, упомянутой в SQL-запросе, даже если эти индексы охватывают столбцы, к которым запрос не обращается. В таблице, упомянутой в SQL-запросе, существуют индексы, базирующиеся на функциях, и индексы, созданные по выражению, которое встречается в запросе. SQL-запрос обращается к таблицам с разбиениями. Существуют таблицы или индексы, предназначенные для параллельной обработки. Оптимизатор интерпретирует их как команду на поиск параллельных планов вьшолнения, которые RBO не поддерживает. Как и растровые индексы, индексы, настроенные со степенью параллелизма, предотвратят использование RBO для таблицы, которая упоминается в SQL, даже если эти индексы охватывают столбцы, к которым SQL не обращается. НЕНАМЕРЕННОЕ ОТКЛЮЧЕНИЕ RBO я много раз встречал такой сценарий: у вас есть стабильное промышленное приложение, хорошо работающее с RBO, и вдруг большие фрагменты приложения начинают работать со скоростью черепахи. Тут же возникает паника и начинается проверка методом тыка . После длительного расследования выясняется, что прошлой ночью администратор базы данных (database administrator, DBA) случайно удалил и создал заново некоторый большой индекс по центральной таблице, возможно, переместив его в новую файловую систему, чтобы освободить больше места. Ваш DBA прозорливо решил, что это был такой большой индекс, что создание его заново старым способом займет недопустимо много времени, поэтому он создал его параллельно, используя подобную конструкцию: CREATE INDEX OrderShip Date ON Orclers(Ship Date) PARALLEL 10; Благодаря этому десять параллельных прюцессов занялись созданием индекса и существенно его ускорили, в то же время оставив время для обычной работы. Пока что все хорошо. Но о чем никто не догадался, так это о том, что у индекса образовалось свойство, заставляющее Oracle использовать стоимостную оптимизацию независимо от конфигурации базы данных и пытаться во всем SQL-коде, в котором упоминается эта таблица, найти планы, использующие этот индекс в параллельных процессах. Так как никто не ожидал, что к этому приложению будет применен СВО, то никто не создал статистику по таблицам и индексам. Поэтому СВО работал без учета правильной статистики и неожиданно выдал ужасные с точки зрения производительности планы для большей части SQL-кода, использующего эту таблицу. Обнаружив причину, проблему можно решить такой командой: ALTER INDEX Orcler Ship Date PARALLEL 1; Поскольку этот оператор лишь настраивает значение в словаре данных, а не перестраивает индекс, он выполняется практически мгновенно, моментально восстанавливая былую производительность приложения. Индексы с подобной ошибкой можно найти, выполнив запрос: SELECT Index Name FROM ALL INDEXES WHERE Degree!=1; Если таблицы и индексы, встречающиеся в вашем SQL-запросе, не запрещают использовать RBO, Oracle делает выбор между RBO и СВО па основе следующих аргументов в порядке использования. L Если после любого ключевого слова SELECT в SQL-запросе (даже в подзапросе или определении представления) присутствует любая допустимая инструкция кроме /*+ RULE */ или /*+ CHOOSE */, Oracle выбирает СВО. 2. Если после любого ключевого слова SELECT в SQL-запросе (даже в подзапросе или определении представления) присутствует /*+ CHOOSE */ и для любой таблицы или индекса, упоминающихся в запросе, не существует статистики, Oracle выбирает СВО. 3. Если после любого ключевого слова SELECT в SQL (даже в подзапросе или определении представления) присутствует /*+ RULE */, Oracle выбирает RBO. 4. Если параметр сеанса optimizer mode устанавливается на уровне сеанса (при помощи ALTER SESSION SET 0PTIMIZER M0DE=<Baffl fib/6op>:), Oracle выбирает RBO или СВО согласно значению этого параметра уровня сеанса. 5. Если параметр opt1mizer mode устанавливается для экземпляра базы данных в файле init.ora, Oracle выбирает RBO или СВО согласно значению этого параметра уровня экземпляра. 6. В ином случае Oracle выбирает оптимизатор согласно значению по умолчанию параметра optiniizer mode, то есть CHOOSE. СМЕШИВАНИЕ СТОИМОСТИ И ПРАВИЛ Значение CHOOSE предлагает возможность смешать стили оптимизации в экземпляре базы данных. Например, можно использовать CHOOSE, если вы хотите использовать два различных приложения. В одном из них SQL-код проверен и оптимален для синтаксической оптимизации, а для другого предпочтительнее будет стоимостная оптимизация. Тогда вам не потребуется генерировать статистику для таблиц, к которым обращается первое приложение, и его SQL-код будет оптимизироваться при помоши RBO. Хотя это звучит привлекательно, я не советую делать подобным образом. Есть шанс, что таблицы, которые используют два приложения, будут пересекаться, иначе, зачем бы вы помещали их в один экземпляр базы данных? В этом случае вы получите SQL оптимизированный наихудшим способом - при помощи СВО, но с недостатками, проистекающими от отсутствия статистики по одной или нескольким таблицам. Даже если вы полностью разъединили наборы таблиц для двух приложений, высока вероятность того, что кто-то когда-нибудь создаст статистику по некоторым таблицам, предназначенным для приложения, использующего RBO. И снова в результате вы получите организованные наихудшим способом стоимостные планы для SQL, где перемешаны таблицы, для которых есть статистика, и для которых нет. Гораздо безопаснее использовать отдельные экземпляры и устанавливать значение параметра optimizer mode=rule на уровне экземпляра для каждого приложения. Или же пусть одно из приложений явно установит параметр optimizer niode при подключении к базе данных, перекрывая значение optlmizer riode уровня экземпляра, которое применяется при выборе оптимизатора для другого приложения. Вот как быстро можно проверить значение параметра уровня экземпляра optimizer mode: SELECT VALUE FROM V$PARAMETER WHERE NAME = optimizer mode: В трех последних шагах последовательности решений Oracle делает выбор на основе значения параметра opt1m1zer mode, которое устанавливаете вы или администратор вашей базы данных. Допустимы четыре возможных значения параметра, которые влияют на выбор следующим образом. RULE. Oracle использует синтаксическую оптимизацию. ALL ROWS. Oracle использует стоимостную оптимизацию с целью минимизировать стоимость всего запроса. Этот режим по умолчанию стоимостной оптимизации иногда выдает ненадежные планы (планы, в которых используются методы соединения, отличные от вложенных циклов) со всеми рисками, описанными в главе 6. Однако оптимизатор выбирает эти планы только если считает, что они выполняются быстрее, чем наилучшие надежные планы. FIRST ROWS. Oracle использует стоимостную оптимизацию с целью минимизировать стоимость получения первых строк из запроса. На практике обычно выбираются надежные планы со вложенными цигшами, схожие с теми, которые выбирает синтаксический оптимизатор. Но в данном случае при построении планов учитывается больше информации о распределении данных и возможной стоимости выполнения. Уровень оптимизации FIRST ROWS создает тот же эффект, что и подсказка OPTIMIZE FOR 1 ROW в DB2 и подсказка OPTIONCFAST1) в SQL Server. CHOOSE. Oracle использует стоимостную оптимизацию с той же целью что и в случае использования значения ALLROWS. Если же для таблиц или индексов, упомянутых в запросе, нет статистики оптимизации, Oracle использует синтаксическую оптимизацию.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |