Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Тоу Д. -> "Настройка SQL. Для профессионалов" -> 47

Настройка SQL. Для профессионалов - Тоу Д.

Тоу Д. Настройка SQL. Для профессионалов — СПб.: Питер, 2004. — 333 c.
ISBN 5-94723-959-0
Скачать (прямая ссылка): nastroykasqldlyaprof2004.djvu
Предыдущая << 1 .. 41 42 43 44 45 46 < 47 > 48 49 50 51 52 53 .. 161 >> Следующая


I--Table Scan(...(...[Employees] AS [E]).

(wrapped line) WHERE:([E].[Last_Name]=‘Stevenson'))

I-Fi I ter(WHERE:(upper([LE], [Description])=

(wrapped line) 'SAN FRANCISCO'))

I--Table Scan(...(...[Locations] AS [LE]))

(8 row(s) affected)

Здесь любой доступ к таблице выполняется путем полного сканирования таблицы. Запрос начинает выполняться на LE и отфильтровывает местоположения с подходящим описанием. Следующая таблица, к которой производится доступ, — это Е, из которой отфильтровываются сотрудники с подходящей фамилией. Полученные из этих двух таблиц строки хэшируются и соединяются. Затем результат соединяется хэшированием с результатом полного сканирования M и, в итоге, с результатом полного сканирования LM.

Сложные планы выполнения

Существуют и другие возможности планов выполнения, например индикаторы, указывающие, какие из соединений являются внешними, перечисление шагов сор-
94

3. Просмотр и интерпретация планов выполнения

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

SELECT E.First_Name, Е.Nickname. E.LastName.

E.Phone_Number, L.Description FROM Employees E

INNER JOIN Locations L DN E.Location_ID=L.Location_ID WHERE (E.First_Name= ? OR E.Nickname= ?)

AND EXISTS (SELECT I FROM Wage_Payments P

WHERE P.Employee_ID=E.Employee_ID

AND P.PaymentJlate > CURRENT DATE - 31 DAYS);

Оставьте все таблицы пустыми. Создайте следующие индексы.

¦ Employees(First_Name)

¦ Employees(Nickname)

¦ Locatіons(Location_ID)

¦ Wage_Payments(Employee_ID)

Будет создан следующий план выполнения:

StmtText

SELECT E.First_Name, Е.Nickname. E.Last_Name.

E.Phone_Number. L.Description FROM Employees E. Locations L WHERE (E.First_Name=‘Kathy' OR E.Nickname=’Kathy')

AND E.Location_ID=L.Location_ID AND EXISTS (SELECT null

FROM Wage_Payments P

WHERE P.Employee_ID=E.Employee_ID

AND P.Payment_Date > DATEADD(DAY.-31.GETDATE( ))):

(I row(s) affected)

StmtText

!--Nested Loops(Left Semi Join)

|--Filter(WHERE:([E].[First_Name]='Kathy' OR [E].[Nickname]=1Kathy'))

I |--Bookmark Lookup(...(...[Employees] AS [E]))

I |--Nested Loopsdnner Join)

I I--Table Scan(...(...[Locations] AS [L]))

I I--Index Seek(...[Employees],[Employee Location ID]

(wrapped line) AS [E]). SEEK:([E].[Location_ID]=[L].[Location_ID]) DRDERED) |--Filter(WHERE:([P].[Payment_Date]>dateadd(4. -31. getdate( ))))

!--Bookmark Lookup(...(...[Wage_Payments] AS [P]))

I--Index

(wrapped line) Seek(...(...[Wage_Payments].[Wage_Payment_Employee_ID]

(wrapped line) AS [P]). SEEK:([P].[EmployeeJD]=[E].[Employee_ID]) ORDERED)

(9 row(s) affected)

Этот план выполнения демонстрирует полное сканирование таблицы Locations как ведущей таблицы, так как к ней производится первое обращение на самом глубоком уровне вложенности. Затем SQL Server выполняет вложенные циклы по индексу по внешнему ключу Employee_Location_ID, чтобы присоединить Employees.
Чтение планов выполнения в SQL Server

95

После обработки таблицы Empl oyees SQL Server отбрасывает строки, не удовлетворяющие условию для полей Fi rst_Name и Nickname. Далее выполняется специальное соединение, называемое полусоединением, чтобы достигнуть коррелированного подзапроса на присоединение подходящих записей из Employee_ID с использованием индекса Wage Paynient Employee ID. При помощи идентификаторов строк из этого индекса производится обращение к Wage_Payments, после чего условие последнего фильтра по Payment_Date отбрасывает старые строки, не удовлетворяющие подзапросу EXISTS. Соединение с коррелированным подзапросом EXISTS показано в самом первом шаге, который описан как Left Semi Joi п. Этот результат не является оптимальным планом выполнения для заполненных таблиц, но так как тестирование проводилось на пустых таблицах, я бы и не ожидал появления плана исполнения, подходящего для больших объемов данных.
Управление планами выполнения

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

Для управления планами выполнения было придумано множество сложных инструментов. Эта глава сосредоточена на простейших способах управления планами, с акцентом на получение планов таких типов, которые вам понадобятся для оптимизации реального SQL. Я обнаружил, что если заранее знать, какой план выполнения вы хотите получить, то процесс существенно упрощается и требует лишь простейших инструментов.
Предыдущая << 1 .. 41 42 43 44 45 46 < 47 > 48 49 50 51 52 53 .. 161 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100