查询优化(1)
--最近在看Inside Microsoft SQL Server 2005:Query Tuning and Optimization一書。其中有一段內容感覺歸納得不錯,糾正了我以前的一些錯誤概念。
對查詢我們可以從以下幾個方面來考慮進行優化。
重寫查詢語句
- 除了盡量避免太復雜的謂詞判斷,我們還需要盡可能避免使用outer joins,cross apply,outer apply,correlated scalar subqueries(關聯標量子查詢)或其他太過復雜的子查詢。
- 在某些情況下,把查詢中的非關聯標量子查詢分離為一個獨立的查詢,并把此獨立查詢的結果保存在一個變量中供后續查詢使用將會對整個查詢的性能有所幫助。這樣做還可能對使用并行執行計劃帶來幫助。
- 盡量避免在并行執行計劃中使用dynamic index seeks動態索引查找。
注:什么是Dynamic Index Seeks
比較以下2個查詢的執行計劃,其中第2個查詢使用了Dynamic Index Seeks
--在Northwind中測試 --查詢1 SELECT [OrderId] FROM [Orders] WHERE [ShipPostalCode] IN (N'05022', N'99362')--查詢2 DECLARE @SPC1 nvarchar(20), @SPC2 nvarchar(20) SELECT @SPC1 = N'05022', @SPC2 = N'99362' SELECT [OrderId] FROM [Orders] WHERE [ShipPostalCode] IN (@SPC1, @SPC2)- 盡可能使用inline table-valued functions(內聯表值函數)代替multistatement TVFs(多語句表值函數)。特別應避免對參數化的多語句表值函數進行cross apply。
- 盡可能使用基于集合操作的查詢,避免使用游標。
優化Schema
- 如果對于一個高選擇性的謂詞,執行計劃仍使用索引掃描或表掃描,我們應考慮增加一個合適的索引來使優化器使用索引查找。對于使用nested loops join的查詢,可考慮給連接的內層表加上合適的索引。一個執行計劃如果由于含有bookmark lookup而開銷很大時,可以考慮通過增加一個索引來覆蓋所有需要取出的列。
- 如果查詢計劃中的merge join或stream aggregate之前有sort運算符,我們可以考慮增加一個索引來提供需要的排序。如果有可能的話,盡量創建一個唯一索引或約束,這樣優化器會選擇使用一對多的merge join代替多對多的merge join。盡可能使創建的唯一索引包含最少的列。
- 考慮創建合適的外鍵,NOT NULL和CHECK約束。外鍵約束能簡化連接,把一些outer或semi joins轉化為inner joins(或把一個full outer join轉化為一個left或right outer join)。Check約束也能減少一些多余的謂詞。
- 盡可能避免把兩張表中的不同類型的數據列進行連接。特別需要避免主鍵和外鍵的數據類型不符。連接不同類型的數據列可能會使SQL Server無法使用index seeks,降低查詢性能,也可能引起語義錯誤。
轉載于:https://www.cnblogs.com/DBFocus/archive/2010/06/10/1755320.html
總結
- 上一篇: 兰州交通大学计算机科学与技术学院,兰州交
- 下一篇: Java的组合排列问题