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

1 ... 21 22 23 [ 24 ] 25 26 27 ... 107


В других операционных системах, отличных от Unix, можно попробовать подобные фокусы или же просто дописать содержимое файла head. sql в начало tmp. sql, содержимое tai 1. sql в конец tmp. sql и выполнить сценарий целиком. Это работает во всех операционных системах. Вот пример выполнения этого процесса на том же запросе, который я рассматривал ранее, начиная с команды qui t, чтобы выйти в строку приглашения оболочки: с1Ь2 => quit;

DB20000I The QUIT conrnand completed successfully. $ cat head.sql tmp.sql tail.sql db2 +c +p -t DB20000I The SQL command completed successfully. DB20000I The SQL command completed successfully.

OPERATOR ID TARGET ID OPERATORJYPE OBJECT NAME COST

1 - RETURN - 186

2 1 TBSCAN - 186

3 2 SORT - 1B6

4 3 FETCH EMPLOYEES 186

5 4 IXSCAN EMP MGR ID 25

5 record(s) selected.

DB20000I The SQL command completed successfully. $

Ha практике оказывается, что половина всех изменений, которые вы внесете при настройке плана вьшолнения, будет сделана в tmp.sql, а вторая половина - в среде базы данных при помощи интерфейса командной строки db2. Это будет создание и удаление индексов, создание статистики по таблицам и индексам или изменение параметров для оптимизации сеанса.

Надежные планы выполнения

При настройке SQL вы обычно хотите убедиться, что получаете простые планы вьшолнения, которые выполняют вложенные циклы в правильном порядке соединения. Я называю такие планы вьшолнения надежными, так как они обычно хорошо справляются с большими объемами данных. В этом примере возвращается надежный план, упрощающий процесс, для следующего кода SQL, записанного в tmpsql:

-- File called tmp.sql

SELECT E.First Name. E.Last Name. E.Salary. LE.Description.

M.First Name. M.Last Name. LM.Description FROM Employees E

INNER JOIN Locations LE ON E.Location ID=LE.Location ID INNER JOIN Employees M ON E.Manager ID=M.Employee ID INNER JOIN Locations LM ON M.Location ID=LM.Location ID WHERE E.Last Name = ? AND UCASE(LE.Description) = ? :

Чтобы продемонстрировать этот код на реальных данных, я поместил в таблицу Empl oyees 100 ООО строк, причем для LastName у меня есть 10 ООО различных значений. В таблицу Locations я поместил 1 ООО строк. После подключения к DB2 в каталоге, где находятся файлы tmp.sql, head .sql и tai 1. sql, я вышел в командную строку оболочки. Затем выполнил команду cat head. sql tmp. sql tai 1. sql db2 +c +p -



t и получил следующий выход с индексами только по первичным ключам

и Emp1oyees(Last Name):

$ cat head.sql tmp.sql tail.sql db2 +c +p -t DB20000I The SOL conmand completed successfully. DB20000I The SOL command completed successfully.

OPERATOR ID TARGET ID OPERATOR TYPE OBJECT NAME COST

- RETURN

1 NLJOIN

2 NLJOIN

3 NLJOIN

4 FETCH

EMPLOYEES

5 IXSCAN

EMP LAST NAME

4 FETCH

LOCATIONS

7 IXSCAN

LOCATION PKEY

3 FETCH

EMPLOYEES

9 IXSCAN

EMPLOYEE PKEY

2 FETCH

LOCATIONS

11 IXSCAN

LOCATION PKEY

12 record(s) selected.

DB20000I The SQL command completed successfully. $

Интерпретация плана

План выполнения читается следующим образом.

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

Порядок доступа к таблицам - Employees, Locations, Employees, Locations. В том же самом порядке они перечислены в плане выполнения. Когда SQL обращается к одним и тем же таблицам несколько раз, псевдонимы для таблиц обязательны. Как можно видеть в примере в разделе FROM, для таблицы Employees есть два псевдонима - Е и М. Изучая индекс, можно понять, что именно псевдоним Е, а не псевдоним М представляет ведущую таблицу, хотя оба псевдонима указывают на одну и ту же таблицу Empl oyees. Не так очевидно, к какому из псевдонимов для Locations база данных обращается первой, но это должен быть LE, так как только к нему можно обратиться вторым в порядке соединения.

Все четыре операции считывания из таблиц производятся при помощи индекса, на что указывает OPERATOR TYPE FETCH перед каждым именем таблицы. Используемые индексы указаны в записях OPERATORTYPE IXSCAN под записями о доступе к каждой таблице. Так, вы знаете, что обращение к ведущей таблице Е производится путем сканирования индекса EMP LAST NAME (причем считывание хотя бы потенциально затрагивает несколько строк за раз). Все остальные операции доступа к таблицам - это уникальные считывания, так как в них используются условия уникальности для первичных ключей таблиц. Так как все операции считывания, которые выполняются после обработки ведущей таблицы, относятся к уникальным соединениям, вы знаете, что максимальное количе-



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

ВНИМАНИЕ -

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

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

-- File called inddb2.sql

SELECT IndName. ColNames

FROM SYSCAT.INDEXES

WHERE TabName = UCASECEMPLOYEES):

В DB2, войдя в схему, содержащую таблицу, которую вам необходимо проверить, отредактируйте сценарий, указав нужную таблицу, и выполните в строке приглашения оболочки команду db2 -tf inddb2. sql. Будут по порядку перечислены многостолбцовые индексы начиная с первого столбца - в одной строке, разделенные знаком +. Далее показан пример использования сценария: $ db2 -tf inddb2.sql

INDNAME COLNAMES

EMP MGR ID +MANAGER ID

EMPLOYEE PKEY +EMPLOYEE ID

EMP LOCATION ID +LOCATION ID

EMP DEPARTMENT ID +DEPARTMENT ID

EMP HIRE DATE +HIRE DATE

EMP LAST NAME +LAST NAME

EMPJICKNAME +NICKNAME

EMP FIRST NAME +FIRST NAME

8 record(s) selected.

Интерпретация плана выполнения

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



1 ... 21 22 23 [ 24 ] 25 26 27 ... 107

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