|
Программирование >> Полное сканирование таблицы
глашением SQL> в том окне, где выполняется сеанс утилиты SQL* Plus. Процесс анализа и просмотра планов выполнения можно описать достаточно детально. L Поместите чистый SQL-код, анализ которого требуется произвести, в файл tmp. sql в том же каталоге, где находятся ех. sql, head. sql и tai 1. sql. 2. В сеансе S QL* Plus, запущенном из того же каталога, в строке приглашения SQL> выполните команду @ех. 3. Просмотрите план вьшолнения. 4. Настройте базу данных (например, изменив индекс) и рассматриваемый SQL-код в ttnp. sql (следуя методам, описанным в главе 4). 5. Сохраните файл tmp.sql и перейдите к шагу 2. Повторяйте действия, пока не получите желаемый план выполнения, а затем сохраните правильный результат где-либо для постоянного хранения. Теперь для того, чтобы внести изменения и увидеть результаты, требуется потратить лишь несколько секунд. Если вы хотите распечатать план выполнения или просмотреть его в текстовом редакторе (особенно если он большой), то это тоже можно сделать практически мгновенно, поскольку он хранится в файле tmp.out. В других операционных системах, отличных от Unix, тоже можно попробовать использовать подобные методы работы или же просто дописать содержимое файла head. sql в начало tmp. sql, содержимое tai 1. sql в конец tmp. sql и выполнить Ptmp в строке с приглашением SQL>. Этот вариант можно использовать во всех операционных системах. На практике оказывается, что половина всех изменений, которые вы внесете при настройке плана выполнения, будет сделана в tmp. sql, а вторая половина - в среде базы данных при помощи SQL*Plus. Причем это может быть создание и удаление индексов, создание статистики по таблицам и индексам или изменение параметров для оптимизации сеанса. Надежные планы выполнения При настройке SQL вы обычно хотите убедиться, что получаете простые планы вьшолнения, которые выполняют вложенные циклы в правильном порядке соединения. Я называю такие планы выполнения надежными, так как они обычно хорошо справляются с большими объемами данных. В этом примере возвращается надежный план, упрощающий процесс, для следующего кода SQL, записанного в tmp.sql: -- File called tmp.sql SELECT /*+ RULE */ E.First Name. E.Lastjame. E.Salary. LE.Description. M.First Jame. M.Lastjame. LM.Description FROM Locations LE. Locations LM. Employees M. Employees E WHERE E. Last Jame = :1 AND E.Manager ID=M.Employee ID AND E.Location ID=LE.Location ID AND M.Location ID=LM.Location ID AND UPPER(LE.0escription)=:2: Если в утилите SQL*Plus, запущенной из каталога, где находятся tmp.sql, head. sql, tall.sql и ex.sql, выполнить команду (?ex из строки с приглашением SQL>, то мы получим следующий ответ с индексами только по первичным ключам и по Empl oyees (Lastjame): ПРИМЕЧАНИЕ в предыдущем примере подсказка RULE использовалась исключительно для удобства. Это не означает, что вы должны предпочесть синтаксический оптимизатор RULE - это всего лишь удобный способ получения воспроизводимого плана с вложенными циклами на пустых таблицах, что я и хотел продемонстрировать. Как интерпретировать план Для чтения полученного плана выполнения применяется определенная последовательность операций. Все соединения проводятся методом вложенных ци1слов и показаны как вложенная группа строк NESTED LOOPS. Если вы используете разные методы соединения, то первым будет выполнено самое внутреннее соединение (с самым большим отступом в записи), то есть последнее перечисленное. Порядок вьшолнения соединений следует читать изнутри наружу или снизу вверх. ПРИМЕЧАНИЕ Стандартный способ отображения планов выполнения в Oracle может несколько смутить начинающего разработчика. Если бы вы собирались реализовать похожие вложенные циклы в виде собственной процедуры, то первое соединение, показанное как цикл, находящийся максимально глубоко, было бы на самом деле внешним циклом в реальной структуре вложенных циклов! Когда я писал первый черновик главы 2, то по ошибке назвал выполняемое первым соединение с вложенными циклами циклом с наибольшей глубиной, поскольку так привык к способу отображения планов выполнения в Oracle. Конечно, альтернативный метод отображения мог бы быть полезен, если бы всем удалось к нему немедленно привыкнуть. К сожалению, множество инструментов и огромное количество практики и обучения приучили разработчиков в Oracle использовать именно такую форму вывода результатов, поэтому попытка изменить что-либо привела бы к неразберихе. Если вы новичок в этом деле, мужайтесь - скоро и вы привыкнете. Порядок доступа к таблицам. Дважды происходит обращение к таблице ЕшрТ oyees, а затем дважды к таблице Locati ors. В таком же порядке они перечислены в плане выполнения. Когда сервер обращается к одним и тем же таблицам несколько раз, псевдонимы для таблиц обязательны. Как можно видеть в примере в выражении FROM, для таблицы ЕшрТ oyees есть два псевдонима - Е и М. Изучая индек- SQL> @ех PLAN SELECT STATEMENT NESTED LOOPS NESTED LOOPS NESTED LOOPS TABLE ACCESS BY INDEX ROWID 4*EMPL0YEES INDEX RANGE SCAN EMPLOYEE LAST NAME TABLE ACCESS BY INDEX ROWID 3*EMPL0YEES INDEX UNIQUE SCAN EMPLOYEEPKEY TABLE ACCESS BY INDEX ROWID 2*L0CATI0NS INDEX UNIQUE SCAN LOCATIONPKEY TABLE ACCESS BY INDEX ROWID 1*L0CATI0NS INDEX UNIQUE SCAN LOCATION PKEY SQL> сы, можно понять, что именно псевдоним Е, а не псевдоним М, представляет ведущую таблицу, хотя оба псевдонима указывают на одну и ту же таблицу Employees. Не настолько понятно, к какому из псевдонимов для Locations база данных обращается первой. Здесь нам помогают номера перед именами таблиц. Они указывают порядок перечисления псевдонимов в выражении FROM, поэтому вы знаете, что первый псевдоним для Locations, LE, - это последний псевдоним, к которому обращается план выполнения. ПРИМЕЧАНИЕ Добавление номера перед именем таблицы - это единственное реальное изменение, которое я внес по сравнению со стандартной формой, где разработчики Oracle просматривают планы выполнения. Добавление выражения TO CHAR(OBJECT INSTANCE) Ц * в код SQL для просмотра плана позволяет избежать двусмысленности. Номера помогают в случаях, когда одна таблица несколько раз появляется в выражении FROM, но один из возможных порядков соединения псевдонимов важнее, чем другой. Все четыре операции считывания из таблиц производятся через индекс, на что указывает фраза TABLE ACCESS BY INDEX ROWID перед каждым именем таблицы. Используемый индекс и указание того, гарантируется ли его уникальность, можно найти в записях с отступом под строкой с описанием доступа к каждой таблице. Так, вы знаете, что к ведущей таблице Е доступ осуществляется путем сканирования диапазона индекса EMPLOYEE LAST NAME (причем считывание хотя бы потенциально затрагивает несколько строк за раз). Операции считывания из остальных таблиц - это уникальные считывания через первичные ключи таблиц. Так как все операции считывания, которые выполняются после обработки ведущей таблицы, относятся к уникальным соединениям, вы знаете, что максимальное количество строк, которые запрос может считать из любой из оставшихся таблиц, равно количеству строк, считанных из ведущей таблицы. ВНИМАНИЕ Для этого примера я взял имена индексов, при помощи которых несложно понять, какой индексированный столбец обеспечивает доступ к таблице, но чаще всего индексы имеют не такие понятные имена. Если вам не совсем понятно, какой столбец или столбцы составляют используемый индекс - не гадайте! Одна из наиболее распространенных ловушек при настройке в Oracle - это неоправданное предположение, что сканирование некоего диапазона индекса является сканированием именно желаемого диапазона индекса. Когда вы видите уникальные операции сканирования индекса, то можете с уверенностью сказать, что они обслуживают условия равенства по уникальному ключу. Обычно существует только один столбец или комбинация столбцов, который может охватить индекс, чтобы обеспечить уникальное сканирование. Сканирование диапазона индекса - это совсем другое дело. Если вы не знаете, какие индексы существуют для таблицы и как называются индексы для каждой комбинации столбцов, а также, если имена индексов не позволяют понять, какие столбцы обрабатываются ими, всегда проверяйте индексы - на случай, если сканирование проводится не по тому диапазону индекса, который вы ожидаете. Вот простейший сценарий проверки: -- File called index.sql column column name format a40 set pagesize 999 SELECT INDEX NAME. COLUMN NAME
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |