mssql2005最佳化暗示

sqysl發表於2009-06-09
來自《Microsoft.Press.Inside.Microsoft.SQL.Server.2005.Query.Tuning.and.Optimization.Sep.2007》
Chapter 4. Troubleshooting Query Performance---Query Improvements
前幾天看完了執行計劃那部分後,大體瀏覽了一下最佳化暗示的使用,為了預防今後忘記,抓緊時間記下來,寫一下大體的敘述吧,具體情況的話,今後在認真研究:
一、查詢暗示:
1、FAST N Hint:是一個面向目標的暗示,告訴最佳化器,選擇一個能儘快產生頭N條記錄的執行計劃,例如:
SELECT [OrderId], [CustomerId], [OrderDate]
FROM [Orders]
ORDER BY [OrderDate]
OPTION (FAST 1)
2、OPTIMIZE FOR Hint:為另一個面向目標的暗示,是MSSQL2005裡新增加的,它要求查詢最佳化器基於你確定的引數產生一個計劃,例如:
DECLARE @ShipCode nvarchar(20)SET @ShipCode = N'05022'SELECT [OrderId], [OrderDate]FROM [Orders]WHERE [ShipPostalCode] = @ShipCodeOPTION (OPTIMIZE FOR (@ShipCode = N'05022'))
        
3、Query-Level Join Hints:這些暗示強制最佳化器使用一個確定的連線方式,例如:neted loop join,merge join,hash join,如下:
SELECT O.[OrderId]FROM [Customers] C JOIN [Orders] O ON C.[CustomerId] = O.[CustomerId]WHERE C.[City] = N'London'OPTION (MERGE JOIN)
4、GROUP Hints:用來強制使用匯總方式,例如:order group,hash group,如下:SELECT [CustomerId], MAX([OrderDate])FROM [Orders]GROUP BY [CustomerId]OPTION (HASH GROUP)
5、UNION Hints:強制使用連線操作,例如: CONCAT UNION, MERGE UNION, and HASH UNION,如下:
SELECT [CustomerId]FROM [Orders]WHERE [ShipCity] = N'London'UNIONSELECT [CustomerId]FROM [Customers]WHERE [City] = N'London'OPTION (MERGE UNION)
二、強制順序(Force Order):
1、Forcing Join Order:FORCE ORDER 強制最佳化器產生的計劃按照FROM後面表的順序進行表間的連線,例如:
SELECT O.[OrderId]FROM [Customers] C JOIN [Orders] O JOIN [Employees] E   ON O.[EmployeeId] = E.[EmployeeId] --首先連線,形成左樹連線   ON C.[CustomerId] = O.[CustomerId]WHERE C.[City] = N'London' AND E.[City] = N'London'OPTION (FORCE ORDER, HASH JOIN)SELECT O.[OrderId]FROM [Customers] C JOIN [Orders] O   ON C.[CustomerId] = O.[CustomerId] --先連線,形成右樹連線   JOIN [Employees] E ON O.[EmployeeId] = E.[EmployeeId]WHERE C.[City] = N'London' AND E.[City] = N'London'OPTION (FORCE ORDER, HASH JOIN)
此外,還可以使用FORCE ORDER 來改變Aggregation計劃中的位置,如果使用FORCE ORDER ,並且查詢帶有一個GROUP BY子句,那麼Aggregation會放在子查詢連線後及其他和子查詢無關的連線的前面中間,例如:
SELECT O.[CustomerId], COUNT(*)FROM [Customers] C JOIN [Orders] O   ON C.[CustomerId] = O.[CustomerId]WHERE C.[Country] = N'USA'GROUP BY O.[CustomerId]OPTION (FORCE ORDER)
三、其他暗示:
1、MAXDOP N Hint:該暗示可以改變查詢執行的並行度。
2、EXPAND VIEWS Hint:僅僅用於企業版,該暗示阻止最佳化器匹配索引檢視;
四、表暗示:INDEX, NOEXPAND, and FASTFIRSTROW
1、INDEX hint:可以強制最佳化器使用一個特定的索引(或堆)來進行掃描或搜尋;
(1)Eliminating a Bookmark Lookup,例如:
SELECT [OrderId], [CustomerId]FROM [Orders] WITH (INDEX(1))  --使用索引號為1的索引,索引號可以查詢系統
WHERE [ShipPostalCode] = N'99362' --檢視來獲取
(2)Forcing a Bookmark Lookup,例如:
DECLARE @ShipCode nvarchar(20)SET @ShipCode = N'99362'SELECT [OrderId], [CustomerId]FROM [Orders] WITH (INDEX([ShipPostalCode]))WHERE [ShipPostalCode] = @ShipCode
(3)Multiple Nonclustered Indexes:在多個非簇索引裡選用某個索引,例如:
SELECT [OrderId], [CustomerId]FROM [Orders] WITH (INDEX([OrderDate], [ShipPostalCode]))WHERE [OrderDate] = '1998-02-26' AND [ShipPostalCode] = N'99362'
(4)Index Union:如果表上有唯一性索引,可以強制產生一個模擬索引連線(INDEX UNION)的計劃,例如:
SELECT [OrderId], [CustomerId]FROM [Orders]WHERE [OrderDate] = '1998-02-26' OR [ShipPostalCode] = N'83720'

SELECT [OrderId], [CustomerId]FROM [Orders] WITH (INDEX([OrderDate]))WHERE [OrderDate] = '1998-02-26'UNIONSELECT [OrderId], [CustomerId]FROM [Orders] WITH (INDEX([ShipPostalCode]))WHERE [ShipPostalCode] = N'83720'
(5)Detecting INDEX Hints in a Query Plan:透過屬性視窗和XML計劃,我們可以檢視索引暗示:
  
2、NOEXPAND Hint:阻止MSSQL顯式的擴充套件一個索引檢視的定義。
3、FASTFIRSTROW Hint:用於查詢中的任何一個表上,而FIRST N則用於整個查詢。
4、ANSI-Style. Join Hints:允許更好的控制連線順序和連線型別,例如:
SELECT O.[OrderId]FROM [Employees] E INNER MERGE JOIN   (       [Customers] C INNER LOOP JOIN       [Orders] O       ON O.[CustomerId] = C.[CustomerId]   )   ON O.[EmployeeId] = E.[EmployeeId]WHERE   C.[City] = N'London' AND   E.[LastName] = N'Peacock'
(5)USE PLAN Hint:是MSSQL2005裡的新特點,它可以透過告訴最佳化器你希望產生的XML計劃來強制一個計劃。例如:
SET SHOWPLAN_XML ONGOSELECT O.[OrderId]
FROM [Employees] E INNER MERGE JOIN   (       [Customers] C INNER LOOP JOIN       [Orders] O       ON O.[CustomerId] = C.[CustomerId]   )   ON O.[EmployeeId] = E.[EmployeeId]WHERE   C.[City] = N'London' AND   E.[LastName] = N'Peacock'GOSET SHOWPLAN_XML OFFGO
SELECT O.[OrderId]FROM [Employees] E JOIN   (       [Customers] C JOIN       [Orders] O       ON O.[CustomerId] = C.[CustomerId]   )   ON O.[EmployeeId] = E.[EmployeeId]WHERE   C.[City] = N'London' AND   E.[LastName] = N'Peacock'OPTION (USE PLAN N' ... ')

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8484829/viewspace-605581/,如需轉載,請註明出處,否則將追究法律責任。

相關文章