国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > SQL Server > 正文

SQL Server 2012:SQL Server體系結(jié)構(gòu)——一個查詢的生命周期(第2部分)

2024-08-31 00:54:34
字體:
供稿:網(wǎng)友
SQL Server 2012:SQL Server體系結(jié)構(gòu)——一個查詢的生命周期(第2部分)計劃緩存(Plan Cache)

如果SQL Server已經(jīng)找到一個好的方式去執(zhí)行一段代碼時,應(yīng)該把它作為隨后的請求重用,因?yàn)樯蓤?zhí)行計劃是耗費(fèi)時間且資源密集的,這樣做是有有意義的。

如果沒找到被緩存的計劃,然后命令分析器(Command Parser)在T-SQL基礎(chǔ)上生成一個查詢樹(query tree)。查詢樹(query tree)的內(nèi)部結(jié)構(gòu)是通過樹上的每個結(jié)點(diǎn)代表查詢中需要的執(zhí)行操作。這個樹然后被傳給查詢優(yōu)化器(Query Optimizer)去處理。我們的簡單查詢沒有一個存在的計劃,因此一個查詢樹(query tree)會被創(chuàng)建,然后傳給查詢優(yōu)化器(Query Optimizer)。

上圖展示了命令分析器(Command Parser)是用來檢查現(xiàn)存執(zhí)行計劃的計劃緩存(plan cache),因?yàn)樵诰彺胬餂]找到我們查詢的任何信息,還有從命令分析器(Command Parser)輸出傳給優(yōu)化器的查詢樹(query tree)。

查詢優(yōu)化器(Query Optimizer)是被SQL Server團(tuán)隊視為最有價值的財產(chǎn),也是產(chǎn)品中最復(fù)雜、機(jī)密的部分之一。幸運(yùn)的是,只有底層的算法和源代碼被很好保護(hù)(即使在微軟內(nèi)部),優(yōu)化器如何工作才能被研究和監(jiān)視。

這個所謂的基于成本(cost-based)的優(yōu)化器,意味要去評估執(zhí)行查詢的各種方式,然后選擇被認(rèn)為擁有最小成本的方式去執(zhí)行。執(zhí)行方式以查詢計劃(query plan)實(shí)現(xiàn)并從查詢優(yōu)化器(Query Optimizer)輸出。

基于剛才的介紹,你認(rèn)為優(yōu)化器的工作是找到最好的查詢計劃會被原諒的,因?yàn)槟强雌饋硎呛苊黠@的設(shè)想。然而它的實(shí)際工作是在一段時間內(nèi)找到好的計劃,而不是最佳計劃。優(yōu)化器的目標(biāo)通常被描述為找最有效率的計劃。

如果優(yōu)化器每次都嘗試去找最好的計劃,比起執(zhí)行一個慢的計劃,找個最好的計劃花費(fèi)的時間更長(一些內(nèi)建的試探法實(shí)際上在保證優(yōu)化器從不花更長的時間找到好計劃,而是就找一個計劃并執(zhí)行它)。

優(yōu)化器同樣在成本的基礎(chǔ)執(zhí)行多級優(yōu)化,在每一階段增加更多可用選擇項(xiàng)來找更好的計劃。當(dāng)一個好計劃被找到時,優(yōu)化器就停在那一階段了。

第1階段被稱之為預(yù)優(yōu)化,當(dāng)語句是足夠簡單而只有一個最佳計劃時,在第一階段就退出剩下的步驟,移除額外成本需要。沒有join的基本查詢被認(rèn)為簡單,計劃成本產(chǎn)出為0,然后被提及為普通計劃(trivial plans)。

優(yōu)化實(shí)際上開始的下一階段包含三個查找時期:

  • 第0時期——這個時期優(yōu)化器會找內(nèi)循環(huán)連接(nested loop joins)且不考慮并行運(yùn)算符(parallel Operators)。

如果已經(jīng)找到的計劃成本小于0.2,優(yōu)化器會停在這里。在這個階段生成的計劃稱為事務(wù)處理(transaction PRocessing)或簡稱TP計劃。

  • 第1時期——第1時期使用可用優(yōu)化規(guī)則的子集來找常用格式(common patterns)的已有計劃。

如果已經(jīng)知道的計劃成本小于1.0,優(yōu)化器會停在這里。這個階段生成的計劃被稱為快速計劃(quick plans)。

  • 第2時期——在這個最后時期優(yōu)化器全力以赴(pulls out all the stops)使用它所有的優(yōu)化規(guī)則。它同樣也會找下并行(parallelism)和索引視圖(indexed views)(如果你運(yùn)行的是企業(yè)版(Enterprise Edition))。

第2時期的完成是找到計劃的成本對優(yōu)化需要的時間之間的平衡。在這個時期生成的計劃有完全級別(level of "Full")的優(yōu)化。

它的花費(fèi)需要多少?

這里提及的花費(fèi)不能用多少秒或其他有意義的表達(dá)來衡量;它只是標(biāo)記代表計劃資源消耗值的一個任意數(shù)。然而,在早期的微軟SQL Server世界里,它的起源是在桌面電腦上的基準(zhǔn)檢查程序(benchmark)(跑分)。

在計劃里,每個運(yùn)算符都有一個底線成本,然后用它來乘以行的大小和預(yù)計行數(shù)來獲得那個運(yùn)算符的成本,計劃成本就是這些所有運(yùn)算符的成本。

因?yàn)槌杀緛碜杂诘拙€值且與你的硬件速度無關(guān),在每個SQL Server裝置(同比版本 like-for-like version。博主注:與版本無關(guān)。)里生成每個計劃的成本是一樣的。

因?yàn)槲覀兊腟ELECT查詢非常簡單,它退出在預(yù)優(yōu)化時期的操作,因?yàn)檫@個計劃對優(yōu)化器非常明顯(一個普通計劃)。現(xiàn)在已經(jīng)有查詢計劃了,它向查詢執(zhí)行器(Query Executor)去執(zhí)行。

查詢執(zhí)行器(Query Executor)

查詢執(zhí)行器的工作是不釋自明的,它執(zhí)行查詢。更準(zhǔn)確的說,它通過干完包含與存儲引擎相互作用的檢索或修改數(shù)據(jù)的每一步來執(zhí)行查詢。

(此處有信息需要完善…………)

這個SELECT查詢需要檢索數(shù)據(jù),因此請求傳給存儲引擎(Storage Engine)通過OLE DB接口傳給存取方法(access Methods)。

上圖展示了作為優(yōu)化器的輸出的執(zhí)行計劃(query plan)正傳給查詢執(zhí)行器(Query Executor),同時引入了存儲引擎(Storage Engine),它被查詢執(zhí)行器(Query Executor)通過OLE作為接口給存取方法(Access Methods)。

存取方法(Access Methods)

存取方法是為你數(shù)據(jù)和索引提供存儲結(jié)構(gòu),還有通過數(shù)據(jù)檢索或數(shù)據(jù)修改接口的一批代碼。它包含檢索數(shù)據(jù)的所有代碼單本身不執(zhí)行操作,它向緩存區(qū)管理器(Buffer Manager)傳遞請求。

假設(shè)我們的SELECT語句需要讀取一些記錄行的數(shù)據(jù)剛好在一頁。存取方法(Access Methods)的代碼會讓緩存區(qū)管理器(Buffer Manager)檢索頁,因此它可以準(zhǔn)備一個OLE DB的記錄集傳回給關(guān)系引擎(Relational Engine)。

緩存區(qū)管理器(Buffer Manager)

緩存區(qū)管理器(Buffer Manager),如名所示,管理緩沖池(buffer pool),它代表著SQL Server的主要內(nèi)存使用。如果你需要從頁讀一些記錄行(當(dāng)我們談?wù)揢PDATE查詢時會提及修改數(shù)據(jù)),緩存區(qū)管理器(Buffer Manager)在緩沖池(buffer pool)檢查數(shù)據(jù)緩存看看在內(nèi)存里是否有被緩存的這頁。如果這頁已被緩存了,結(jié)果就會傳回給存取方法(Access Methods)。

如果這頁沒被緩存,然后緩存區(qū)管理器(Buffer Manager)從磁盤里拿這頁,把它放入數(shù)據(jù)緩存(Data Cache),然后把結(jié)果傳回給存取方法(Access Methods)。

你這里要記住的要點(diǎn)是你永遠(yuǎn)只和內(nèi)存中的數(shù)據(jù)打交道。在作為記錄集返回前,你請求的每個新的數(shù)據(jù)讀取,首先從磁盤讀取,然后寫回內(nèi)存(數(shù)據(jù)緩存(the data cache))。

這就是為什么SQL Server需要在內(nèi)存里保持最小級別的可用頁面;如果第一時間在緩存里沒有空間來放數(shù)據(jù),你就不能讀取任何新數(shù)據(jù)。

存取方法(Access Methods)代碼決定SELECT查詢需要一個新頁,因此它向緩存區(qū)管理器(Buffer Manager)拿。緩存區(qū)管理器(Buffer Manager)檢查它是否已在數(shù)據(jù)緩存(data cache),如果沒找到的話就從磁盤加載到緩存。

數(shù)據(jù)緩存(Data Cache)

數(shù)據(jù)緩存一直是緩沖池(buffer pool)最大一部分;因此也是在SQL Server最大內(nèi)存用戶。這里每個從磁盤讀取的數(shù)據(jù)頁在被用之前都會被寫回。

這個sys.dm_os_buffer_descriptors動態(tài)管理視圖(DMV)每一行代表當(dāng)前內(nèi)存持有的每個數(shù)據(jù)頁,你可以用這個腳本看看在數(shù)據(jù)緩存區(qū)(Data Cache)每個數(shù)據(jù)庫占用多少空間:

1 SELECT count(*)*8/1024 AS 'Cached Size (MB)'2    ,CASE database_id3         WHEN 32767 THEN 'ResourceDb'4         ELSE db_name(database_id)5         END AS 'Database'6 FROM sys.dm_os_buffer_descriptors7 GROUP BY db_name(database_id),database_id8 ORDER BY 'Cached Size (MB)' DESC

輸出結(jié)果看起來會類似如下:

Cached Size (MB) Database

3287 People

34 tempdb

12 ResourceDb

4 msdb

這個例子里,People數(shù)據(jù)庫在數(shù)據(jù)緩存(Data Cache)里有3287 MB數(shù)據(jù)頁。

頁在緩存里停留時間量由最近最少使用(least recently used:LRU)策略決定。

(此處有信息待完善………………)

一個簡單SELECT語句(查詢)生命周期總結(jié)

SELECT查詢的整個生命周期在這里被介紹:

  1. 在客戶端的SQL Server網(wǎng)絡(luò)接口(SNI)與在SQL Server使用例如TCP/IP的網(wǎng)絡(luò)協(xié)議的網(wǎng)絡(luò)接口(SNI)建立連接。然后在TCP/IP連接上建立與TDS終結(jié)點(diǎn)的聯(lián)系并發(fā)送SELECT語句作為TDS消息發(fā)送給SQL Server。
  2. 在SQL Server上的SNI把TDS消息拆包,讀取SELECT語句,傳送一個“SQL命令”給命令分析器。
  3. 命令分析器在緩沖池檢查計劃緩存是否存在,與語句匹配的可用查詢計劃被命令分析器接收。如果沒有找到它,基于SELECT語句創(chuàng)建查詢樹傳給優(yōu)化器來生成查詢計劃。
  4. 優(yōu)化器在預(yù)編譯生成零成本計劃或普通計劃,因?yàn)檫@個語句太簡單了。生成的查詢計劃然后傳給查詢執(zhí)行器去執(zhí)行。
  5. 在執(zhí)行時,查詢執(zhí)行器決定讀取需要的數(shù)據(jù)來完整這個查詢計劃,因此通過OLE DB接口把請求傳給在存儲引擎里的存取方法。
  6. 存取方法需要從數(shù)據(jù)庫里讀一個頁來完成來自查詢執(zhí)行器的請求,它讓緩存區(qū)管理器來提供這個頁。
  7. 緩存區(qū)管理器檢查數(shù)據(jù)緩存看看它在緩存里是否已有。它不在緩存,因此從磁盤里拿這個頁,放入緩存,傳回給存取方法。
  8. 最后,存取方法把結(jié)果集送回給關(guān)系引擎發(fā)回給客戶端。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 社会| 滦平县| 婺源县| 肇东市| 高清| 健康| 吉水县| 万荣县| 鄂托克旗| 措勤县| 英超| 上饶市| 阿拉善左旗| 威海市| 吴旗县| 台南市| 磴口县| 会昌县| 宁波市| 枣庄市| 宁化县| 即墨市| 安阳县| 霞浦县| 阿巴嘎旗| 永登县| 济源市| 南通市| 西宁市| 广东省| 乌拉特前旗| 宁化县| 黑水县| 富阳市| 黎川县| 浦江县| 兖州市| 康马县| 宜宾市| 志丹县| 阿勒泰市|