亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

SQL Server調優系列玩轉篇(如何利用查詢提示(Hint)引導語句運行)

2024-08-31 00:54:55
字體:
來源:轉載
供稿:網友
SQL Server調優系列玩轉篇(如何利用查詢提示(Hint)引導語句運行)

前言

前面幾篇我們分析了關于SQL Server關于性能調優的一系列內容,我把它分為兩個模塊。

第一個模塊注重基礎內容的掌握,共分7篇文章完成,內容涵蓋一系列基礎運算算法,詳細分析了如何查看執行計劃、掌握執行計劃優化點,并一一列舉了日常我們平常所寫的T-SQL語句所會應用的運算符。我相信你平常所寫的T-SQL語句在這幾篇文章中都能找到相應的分解運算符。

第二個模塊注重SQL Server執行T-SQL語句的時候一些內幕解析,共分為5篇文章完成,其中包括:查詢優化器的運行方式、運行時幾個優化指標值檢測,統計信息、利用索引等一系列內容。通過這塊內容讓我們了解SQL Server為我們所寫的T-SQL語句如何進行優化及運行的。

從本篇進入第三個模塊的內容,該篇為第一篇,該模塊主要讓我們來指導SQL Server進行定向調整,達到優化的目的。本模塊的內容是以前面一系列內容為前提的,希望充分掌握了前面基礎內容,方能進入本模塊內容。

技術準備

數據庫版本為SQL Server2012,利用微軟的以前的案例庫(Northwind)進行分析,部分內容也會應用微軟的另一個案例庫AdventureWorks。

相信了解SQL Server的朋友,對這兩個庫都不會太陌生。

概念理解

談到hint,其實概念很簡單,正如詞義理解:提示,也就是說讓我們通過給予SQL Server提示(hint)讓數據庫運行時按照我們的思路進行,我估計很多不怎么了解SQL Server的童鞋都不怎么知道,因為一般應用的不多。

其實,SQL Server本身的查詢優化器已經做到很好了,所以大部分情況下不需要我們人工干預,自己就能運行的很好,并且最大限度的優化運行項。但是,俗話說:老虎也有打盹的時候,所以,在有些場景下,就需要我們來給數據庫指導一個方向,讓其運行的更流暢。

但是,記住了:你所應用的hint是在現在的場景中基于現有的環境下,相對是一個好的方式,不能確保你所給予的提示(Hint)永久有效,并且隨著時間推移,數據量的變更,你所發出的提示(Hint)有可能會成為數據庫優化的絆腳石。所以沒有充分的把握不要輕易使用Hint,并且最好采用目標導向Hint。

Hint主要分為三類應用:查詢Hint、表Hint、連接Hint。查詢Hint影響整個查詢,主要應用于查詢語句優化,本篇主要分析查詢Hint。

表Hint影響查詢引用的單個表,而連接Hint影響一個單獨的連接。

Hint應用方式分為兩類:目標導向Hint和物理運算符Hint。

目標導向Hint傳遞邏輯的目標給優化器,而不會具體指定優化器應該如何達到這個目標,應該使用什么物理運算符,或者如何排列這些運算符。所以這種運算符使我們所推薦的,原因很簡單:我告訴丫按照這個思路執行就可以,至于怎么達到,自己想辦法!這種方式從長期看對于數據庫的影響會小很多。

另外一個就是物理運算符,此方式就更直接了:直接告訴丫的步驟,你按照這個去做就行。這種方式不推薦,原因很簡單:你的思路暫時會是好的,但是過段時間就不好了。

一、查詢提示(Hint)

首先,查詢提示(Hint)是我們在調優中應用最廣泛的,因為大部分時間我們是在調整查詢的性能。

關于查詢中的優化選項就是在指導SQL Server的連接類型、聚合類型、聯合類型等物理連接運算符。關于此塊的詳細解析,可以參照我調優系列中前幾篇文章,分析的相當的詳細。

a、FAST N Hint提示

關于此方式的提示,我在前面的文章中已經有使用到,在介紹索引那篇文章中,可以點擊這里查看。

首先,這個Hint是一個目標導向hint。提示目標很簡單:告訴數據庫給我速度出前N行數據就可以,而其它的數據你愛咋地咋地。

這個提示最優的應用環境就是:應用系統中的分頁查詢,當然其它環境可以用。有點類似于SELECT TOP N....

其次,在我們的應用環境中,尤其數據量多的情況下,如果這時候我們的場景是:我想速度的看到前面的部分數據,其它的數據你可以稍后再顯示,但是在執行T-SQL的時候,SQL Server會多方面的考慮耗費(cost),然后再平衡各種利弊選擇出它認為相對好的執行計劃去執行,顯然這種方式獲取數據的方式是很浪費的,并且速度就會相對慢很多。

所以,我們利用FAST N Hint提示,這樣,SQL Server會阻止優化器使用哈希連接、哈希聚合、排序、甚至是并行這些大消耗的動作,而轉變成為這N條數據做快速的優化并輸出。這在大數據量的情況下,是一種非常高明的方式。

來個例子:

SELECT OrderID,CustomerID,OrderDate FROM OrdersORDER BY OrderDate

簡單的查詢,并且按照OrderDate排序,不看執行計劃,我們就已經推測出這個執行計劃中最耗損的就是這個OrderDate了,排序永遠是高耗損,這也是為什么各種類型的索引都要提前排序的原因。

然后,我們再來看一下加上這個FAST N Hint提示的執行

SELECT OrderID,CustomerID,OrderDate FROM OrdersORDER BY OrderDateOPTION(FAST 1)

為了快速獲取這一行數據,利用HINT后,改為了索引掃描+書簽查找,因為這是獲取一條數據的最優的一種方式。

因為數據量的關系,所以我上述演示沒能很好的表現出FAST 提示的優越性來,其實在實際生產中,在面臨龐大的數據量的時候,一般利用FAST N提示獲取出部分數據之后,就不再繼續運行了,因為我們關注的就是這一部分數據。

當然,此HINT也有弊端:在快速獲取前N行結果之后,可能會延遲整個查詢的總體相應時間。也就是說,盡管FASTNHINT可能會使優化器快速產生前N個輸出計劃。但是它會使優化器產生一個在結束最后一行前花費更多時間,消耗更多CPU,甚至于更多IO。

b、OPTIMIZE FORHint提示

此HINT是一種非常有用的提示,也是我們在日常中經常使用的。

這個HINT目標很簡單:告訴優化器目標以Hint值進行分配或者執行。此Hint提示是從SQL Server2005版本以上開始支持,能夠根據指定的參數值產生一個計劃,尤其適用于非對稱數據集中,因為這種數據集中數據分布不均勻,不同的參數值可能導致不同的基數評估和不同的查詢計劃,我們可以從不同的參數中選擇一個最優的執行計劃,作為后續不同參數的執行計劃,避免了SQL Server的重新評估和重編譯的耗費的動作。

來個例子:

SELECT OrderID,OrderDateFROM OrdersWHERE ShipPostalCode=N'51100'

此語句很簡單,就是通過查詢郵政編碼(ShipPostalCode),獲取出訂單ID和訂單日期。

來看這個查詢語句,最理想的情況就是直接通過索引查找(index seek)動作獲取出數據。其實最好的方式也是通過INCLUDE將兩列值包含進去。

我們來看一下實際的執行計劃:

SQL Server通過了索引查找+書簽查找方式獲取,這種方式也湊合吧,其實我們還可以繼續優化。

但是,這不是問題重點,問題重點是該段T-SQL一般我們會利用參數進行查詢或者包裝成存儲過程通過傳參調用。是吧??不會你永遠只查詢一個固定值吧....來看語句

DECLARE  @ShipPostalCode NVARCHAR(50)SET @ShipPostalCode=N'51100'SELECT OrderID,OrderDateFROM OrdersWHERE ShipPostalCode=@ShipPostalCode

是吧,這種方式才能做到重用嘛,不過包裝成一個存儲過程或者一個函數等,估計核心代碼肯定就這樣子了。

來看看生成的執行計劃:

本來很爽的非聚集索引查找(Seek),通過我加了一個參數之后變成了聚集索引掃描(Scan)了,聚集索引掃描的性能跟表掃描基本一樣,沒有啥質的提高!

如果該表數據量特別大的話,我們為該語句設計的非聚集索引就失效了。只能通過依次掃描獲取數據了。有意思嗎???沒意思?。?!

怎么解決呢?這就是我們此處提到Hint出場的時候了,告訴數據庫:丫就按照執行 “51100” 的查詢一樣去執行我傳過來的參數。

DECLARE  @ShipPostalCode NVARCHAR(50)SET @ShipPostalCode=N'51100'SELECT OrderID,OrderDateFROM OrdersWHERE ShipPostalCode=@ShipPostalCodeOPTION(OPTIMIZE FOR( @ShipPostalCode=N'51100'))

看到了,這里又回歸了快速的非聚集索引查找(Seek)狀態,并且不受限制于傳過來的參數是啥。

這個提示只是告訴SQL Server查詢按照這個目標值進行操作,并不會實際影響結果值。

當然上面的問題,如果封裝成存儲過程的時候,可以采用重編譯的方式解決,但是相比利用Hint的方式,重編譯帶來的消耗遠大的多。尤其高并發的環境下重編譯所帶來CPU消耗是非常高的。

c、物理連接提示(Hint)

關于物理連接我們在前面的文章中已經詳細的分析了,在SQL Server中共分為三種物理連接方式:嵌套循環、合并、哈希連接。

詳細的內容可以參照我的基礎篇中的鏈接:SQL Server調優系列基礎篇(常用運算符總結——三種物理連接方式剖析)

文章中對三種連接的利弊進行了詳細的對比,并且對三種連接的使用環境進行了詳細的介紹。但是,有時候SQL Server為我們評估的連接并不是最優的,或者說并不是符合我們的要求,這時候,就要利用我們的物理連接提示進行指導。

總共分為三種查詢級別的連接Hint,正好對應三種物理連接運算符,依次是:LOOP JOIN、MERGE JOIN和HASH JOIN

在應用時候,可以指定一個或者多個,如果指定一個,那么查詢計劃中的全部連接使用指定的連接類型,如果指定兩個,SQL Server會在這兩個連接類型中選擇最好的一個,也就是斃掉了第三個。

應用場景蠻多的,根據三種連接的特性,我們可以有選擇的進行提示,比如我們想一個查詢不消耗內存,那么就可以指定OPTION(LOOP JOIN,MERGER JOIN),這樣就去掉消耗內存的哈希連接,當然這是減小內存消耗但會增加執行時間。如果采用了合并連接(MERGER JOIN)方式不會消耗內存,但是合并連接需要提前排序(sort),排序會消耗大量的內存。

當然,有時候嵌套循環連接執行的時間不理想,就可以指定為哈希連接(hash join)進行連接。

來看個例子:

SELECT o.OrderIDFROM Customers C JOIN Orders O ON C.CustomerID=O.CustomerIDWHERE C.City=N'London'

上面的查詢計劃采用了嵌套循環的連接方式,兩張表依次進行循環嵌套執行。

如果,經過測試這里發現采用合并連接的方式更好一點,我們可以采用如下Hint進行提示操作

SELECT o.OrderIDFROM Customers C JOIN Orders O ON C.CustomerID=O.CustomerIDWHERE C.City=N'London'OPTION(MERGE JOIN)

經過調整之后,這時候該語句就利用到了我們設計的非聚集索引,并且由原來的索引SCAN變成了索引Seek運算。

通過如下方式,可以指導SQL Server在哈希連接和合并連接之間做出選擇,但是一定要放棄嵌套循環連接。

SELECT o.OrderIDFROM Customers C JOIN Orders O ON C.CustomerID=O.CustomerIDWHERE C.City=N'London'OPTION(HASH JOIN,MERGE JOIN)

看以看到,經過評估SQL Server還是依然的選擇了合并連接

其實,這個很正常,首先數據量不大,其次是在City列上存在非聚集索引,所以要充分利用,并且在兩張表的CustomerID是都為索引所覆蓋,這就保證了兩張表在這列上都是預先排序(sort)了,這完全滿足了合并連接的條件。當然,默認選擇嵌套循環連接的原因,我估計的原因就一個:兩張表數據量不大。

當然,出來上面的HINT方式可以指定連接的物理連接方式,還有另外更為粗暴的一種方式,強制執行。如下:

SELECT o.OrderIDFROM Customers C INNER MERGE JOIN Orders O ON C.CustomerID=O.CustomerIDWHERE C.City=N'London'

當然,這種方式也手動的達到了指定采用合并連接的方式。

但是,此種方式有嚴重的弊端:

1、通過采用這種方式貌似暫時解決問題了,但是經過一段時間,此連接方式可能會嚴重阻礙數據庫的優化,而要解決此問題就不得不更改代碼。

2、只能粗暴的指定一種物理連接方式,不能順應SQL Server本身自己的優化策略。

上述的方式是非常不推薦的一種,大部分新手會選擇這種方式。

當然,利用Hint的方式是并非一種萬全之策,但在當前基本能解決問題,當運行到一段周期之后,如果當前的HINT干預了SQL Server數據庫的正常運行,我們也可以采用適當的方式予以停用Hint。使數據庫得到完美的平穩的正常運行。后續文章我們依次介紹。

關于Hint這塊的使用,內容還是挺多的,其中一部分還包含鎖提示等,后續文章我們依次介紹,有興趣的童鞋提前關注。

其實Hint是平常我們調優時候一種重要的工具。但是,這個工具的正確的使用則要依靠牢靠的基礎知識掌握和經驗累積。正所謂:厚積薄發!不要輕易的看到了使用場景就妄自的進行盲目的使用。如果使用不當,還會擾亂SQL Server數據庫本身正常的生態環境,得不償失,越調越亂。

所以:施主,三思而行呀......

參考文獻

  • 微軟聯機叢書邏輯運算符和物理運算符引用
  • 參照書籍《SQL.Server.2005.技術內幕》系列

結語

此篇文章先到此吧,關于SQL Server調優工具Hint的使用還有很多內容,后續依次介紹,有興趣的童鞋可以提前關注。

有問題可以留言或者私信,隨時恭候有興趣的童鞋加入SQL SERVER的深入研究。共同學習,一起進步。

文章最后給出前面幾篇的連接,以下內容基本涵蓋我們日常中所寫的查詢運算的分解以及調優內容項,皆為原創,看來有必要整理一篇目錄了.....

SQL Server調優系列基礎篇

SQL Server調優系列基礎篇(常用運算符總結)

SQL Server調優系列基礎篇(聯合運算符總結)

SQL Server調優系列基礎篇(并行運算總結)

SQL Server調優系列基礎篇(并行運算總結篇二)

SQL Server調優系列基礎篇(索引運算總結)

SQL Server調優系列基礎篇(子查詢運算總結)

-----------------以下進階篇-------------------

SQL Server調優系列進階篇(查詢優化器的運行方式)

SQL Server調優系列進階篇(查詢語句運行幾個指標值監測)

SQL Server調優系列進階篇(深入剖析統計信息)

SQL Server調優系列進階篇(如何索引調優)

SQL Server調優系列進階篇(如何維護數據庫索引)

如果您看了本篇博客,覺得對您有所收獲,請不要吝嗇您的“推薦”。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品高潮粉嫩av| 91精品国产精品| 久久视频在线免费观看| 欧美日韩免费网站| 亚洲欧美日韩视频一区| 亚洲热线99精品视频| 国产精品激情av电影在线观看| 亚洲精品一区久久久久久| 久久久精品2019中文字幕神马| 国产免费久久av| 久久久成人av| 亚洲成年网站在线观看| 精品国产美女在线| 亚洲女人被黑人巨大进入| 一本色道久久88综合日韩精品| 91九色国产在线| 久久久女人电视剧免费播放下载| 亚洲老板91色精品久久| 国产精品视频一区二区三区四| 国产主播欧美精品| 精品一区二区三区三区| 欧美中文字幕视频在线观看| 性欧美暴力猛交69hd| 久久久av免费| 国产精品青草久久久久福利99| 亚洲一区二区在线| 色综合久久88| 精品亚洲一区二区三区在线观看| 中文字幕亚洲欧美| www国产91| 91成人天堂久久成人| 亚洲激情在线观看| 久久久91精品国产| 国产精品视频区1| 国语自产精品视频在线看一大j8| 2019最新中文字幕| 成人免费在线视频网址| wwwwwwww亚洲| 久久影院资源站| 国产精品偷伦视频免费观看国产| 国产成人91久久精品| 精品国产一区二区三区久久狼黑人| 97热精品视频官网| 日韩综合视频在线观看| 国模极品一区二区三区| 黄色成人av在线| 欧美性猛交xxxx乱大交蜜桃| 成人久久久久久久| 国产乱肥老妇国产一区二| 国产999视频| 欧洲日本亚洲国产区| 高清一区二区三区四区五区| 国产成人午夜视频网址| 亚洲自拍偷拍色片视频| 日韩av一卡二卡| 亚洲欧美国产一本综合首页| 国产成人一区二区三区小说| 国产精品一区二区三区毛片淫片| 精品亚洲一区二区三区| 亚洲国产精品久久久久秋霞不卡| xxxxx成人.com| 色老头一区二区三区| 国产成人一区二区三区小说| 国产一区深夜福利| 国产欧美日韩中文字幕| 97在线视频免费| 国产精品最新在线观看| 国产婷婷色综合av蜜臀av| 精品国内产的精品视频在线观看| 亚洲精品国产品国语在线| 欧美黑人国产人伦爽爽爽| 国产精品第10页| 2019中文字幕在线免费观看| 欧美一区视频在线| 国产69精品99久久久久久宅男| 色偷偷噜噜噜亚洲男人的天堂| 中文字幕亚洲一区在线观看| 亚洲成人激情在线观看| 91精品国产综合久久香蕉最新版| 国产69精品久久久久9| 成人乱人伦精品视频在线观看| 97在线精品视频| 成人疯狂猛交xxx| 国产a级全部精品| 一区二区三区视频免费在线观看| 欧美日韩国产精品一区| 欧美激情一级欧美精品| 亚洲欧美在线x视频| 亚洲精品小视频| 久久久久久久久久国产精品| 日韩专区在线播放| 97超碰国产精品女人人人爽| 欧美性xxxxxx| 综合网中文字幕| 91精品国产91久久久久| 久久人人爽人人爽人人片av高请| 亚洲综合色激情五月| 亚洲黄色www| 欧美日韩在线观看视频| 久久99国产精品久久久久久久久| 欧美日韩国产va另类| 91高清在线免费观看| 欧美另类暴力丝袜| 亚洲va欧美va国产综合久久| 欧美中文在线免费| 国产婷婷成人久久av免费高清| 日韩a**站在线观看| 精品久久久国产精品999| 日韩电影免费在线观看中文字幕| 精品成人国产在线观看男人呻吟| 啪一啪鲁一鲁2019在线视频| 亚洲精品小视频| 日韩视频免费看| 社区色欧美激情 | 日本一区二区三区在线播放| 亚洲性生活视频| 亚洲美女精品成人在线视频| 欧美黑人性猛交| 亚洲欧美日韩中文在线| 中文字幕视频一区二区在线有码| 久久99国产精品自在自在app| 国产日韩欧美电影在线观看| 亚洲大胆人体av| 日韩在线视频播放| 国产成人自拍视频在线观看| 97视频在线观看成人| 韩国欧美亚洲国产| 一区二区三区四区在线观看视频| 91av视频在线免费观看| xx视频.9999.com| 久久久久一本一区二区青青蜜月| 久久男人的天堂| 国产精品美女主播在线观看纯欲| 国产69久久精品成人| 精品久久久香蕉免费精品视频| 欧美在线日韩在线| 国产精品久久久久7777婷婷| 欧美大片va欧美在线播放| 高潮白浆女日韩av免费看| 九九热r在线视频精品| 亚洲女在线观看| 久久在精品线影院精品国产| 日韩在线资源网| 亚洲天堂一区二区三区| 欧美限制级电影在线观看| 日韩三级影视基地| 亚洲国产成人在线播放| 91网站在线看| 亚洲国产中文字幕久久网| 97超碰蝌蚪网人人做人人爽| 国产一区二区三区在线播放免费观看| 91色视频在线导航| 国语自产偷拍精品视频偷| 亚洲国产精品热久久| 亚洲自拍中文字幕| 日韩精品在线视频美女| 精品福利在线视频| 亚洲一区二区久久久久久| 黄色一区二区在线| 一本色道久久88综合亚洲精品ⅰ| 国产精品aaaa| 欧美与黑人午夜性猛交久久久| 国产欧美日韩精品在线观看| 日本午夜精品理论片a级appf发布|