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

首頁 > 開發 > 綜合 > 正文

查詢內存溢出

2024-07-21 02:46:41
字體:
來源:轉載
供稿:網友
查詢內存溢出

首先我們來看一個帶排序的查詢,點擊工具欄的顯示包含實際的執行計劃。

1 SELECT * FROM AdventureWorks2008R2.Person.Person WHERE FirstName LIKE 'w%' ORDER BY 1

從執行計劃里可以看出,SELECT運算符包含了內存授予(Memory Grant)信息(一般情況下不會出現,這里是因為我們的語句包含排序操作)。內存授予是KB為單位,是當執行計劃中的一些運算符(像Sort/Hash等運算符)的執行,需要使用內存來完成——因此也被稱為查詢內存(Query Memory) 。

在查詢正式執行前,查詢內存必須被SQL Server授予才可以。對于提供的查詢,查詢優化器根據查詢對象的對應統計信息來決定需要多少查詢內存?,F在的問題就是,當統計信息過期了,SQL Server就會低估要處理的行數。在這個情況下,SQL Server對于提供的查詢還是會請求更少的查詢內存。但當查詢真正開始后,SQL Server就不能改變授予的內存大小,也不能請求更多的內存。查詢必須在授予的查詢內存里完成操作。在這個情況下,SQL Server需要把Sort/Hash運算符涌進TempDb,這就意味我們原先在內存里快速操作變成物理磁盤上慢速操作。SQL Server PRofiler可以通過Sort WarningsHash Warning這2個事件來跟蹤查詢內存溢出(Query Memory Spills)。

很遺憾在SQL SERVER 2008(R2)沒有提供這樣的擴展事件來跟蹤內存溢出事件。在SQL Server 2012里才有來解決這個問題。在這個文章里我會向你展示一個非常簡單的例子,由于統計信息過期,你是如何產生內存溢出(Query Memory Spills)。我們來創建一個新的數據庫,在里面創建一個表:

 1 SET STATISTICS IO ON 2 SET STATISTICS TIME ON 3 GO 4  5 -- Create a new database 6 CREATE DATABASE InsufficientMemoryGrants 7 GO 8  9 USE InsufficientMemoryGrants10 GO11 12 -- Create a test table13 CREATE TABLE TestTable14 (15    Col1 INT IDENTITY PRIMARY KEY,16    Col2 INT,17    Col3 CHAR(4000)18 )19 GO20 21 -- Create a Non-Clustered Index on column Col222 CREATE NONCLUSTERED INDEX idxTable1_Column2 ON TestTable(Col2)23 GO

TestTable表包含第1列的主鍵,第2列的非聚集索引,第3列的CHAR(4000)列。接下來我們要用第3列來做ORDER BY,因此在執行計劃里,查詢優化器必須生成明確的排序運算符。下一步我會往表里插入1500條記錄,表里數據的所有值在第2列會平均分布——在表里每個值只出現一次。

 1 -- Insert 1500 records 2 DECLARE @i INT = 1 3 WHILE (@i <= 1500) 4 BEGIN 5     INSERT INTO TestTable VALUES 6     ( 7          @i , 8         REPLICATE('x',4000) 9     )10     11     SET @i += 112 END13 GO

有了這樣的數據準備,我們可以執行一個簡單的查詢,會在執行計劃里好似用獨立的排序運算符:

1 DECLARE @x INT2  3 SELECT @x = Col2 FROM TestTable4 WHERE Col2 = 25 ORDER BY Col36 GO

當我們在SQL Server Profiler里嘗試跟蹤Sort WarningsHash Warning這2個事件時,會發現跟蹤不到。

你也可以使用DMV sys.dm_io_virtual_file_stats,看下num_of_writes列和num_of_bytes_written列,來看下剛才查詢在TempDb是否有活動。當然,這個只有你一個人在使用當前數據庫時有效。

 1 -- Check the activity in TempDb before we execute the sort Operation. 2 SELECT num_of_writes, num_of_bytes_written FROM  3 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1) 4 GO 5  6 -- Select a record through the previous created Non-Clustered Index from the table. 7 -- SQL Server retrieves the record through a Non-Clustered Index Seek operator. 8 -- SQL Server estimates for the sort operator 1 record, which also reflects 9 -- the actual number of rows.10 -- SQL Server requests a memory grant of 1024kb - the sorting is done inside11 -- the memory.12 DECLARE @x INT13 14 SELECT @x = Col2 FROM TestTable15 WHERE Col2 = 216 ORDER BY Col317 GO18 19 -- Check the activity in TempDb after the execution of the sort operation.20 -- There was no activity in TempDb during the previous SELECT statement.21 SELECT num_of_writes, num_of_bytes_written FROM 22 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1)23 GO

可以發現,查詢執行前后沒有任何改變。這個查詢在我的系統里花費了1毫秒。

現在我們有了1500條記錄的表,這就是說我們需要修改20% + 500的數據行才可以觸發SQL Server來更新統計信息。我們來計算下,就可以知道我們需要需要修改800條行數據(500 + 300)。因此讓我們來插入第2列值為2的799條數據。這樣我們就改變了數據的分布情況,當SQL Server還是不會更新統計信息,因為還有一條數據沒有更新,直到這條數據更新了才會觸發SQL Server內部的統計信息自動更新!

我們再次執行剛才的查詢:

 1 -- Check the activity in TempDb before we execute the sort operation. 2 SELECT num_of_writes, num_of_bytes_written FROM  3 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1) 4 GO 5  6 -- Select a record through the previous created Non-Clustered Index from the table. 7 -- SQL Server retrieves the record through a Non-Clustered Index Seek operator. 8 -- SQL Server estimates for the sort operator 1 record, which also reflects 9 -- the actual number of rows.10 -- SQL Server requests a memory grant of 1024kb - the sorting is done inside11 -- the memory.12 DECLARE @x INT13 14 SELECT @x = Col2 FROM TestTable15 WHERE Col2 = 216 ORDER BY Col317 GO18 19 -- Check the activity in TempDb after the execution of the sort operation.20 -- There was no activity in TempDb during the previous SELECT statement.21 SELECT num_of_writes, num_of_bytes_written FROM 22 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1)23 GO

SQL Server就會把排序運算符涌進TempDb,因為SQL Server只申請了1K的查詢內存授予(Query Memory Grant),它的估計行數是1——內存授予和剛才的一樣。

DMV sys.dm_io_virtual_file_stats顯示在TempDb里有活動,這是SQL Server把排序運算符涌進TempDb的證據。

SQL Server Profiler也顯示了Sort Warning的事件。

我們檢查下執行計劃里的估計行數(Estimated Number of Rows),和實際行數(Actual Number of Rows)完全不一樣。

這里的執行時間花費了184毫秒,和剛才的1毫秒完全不一樣。

現在我們往表里再插入1條記錄,再次執行查詢,一切正常,因為SQL Server會觸發統計信息更新并正確估計查詢內存授予(Query Memory Grant):

 1 -- Insert 1 records into table TestTable 2 SELECT TOP 1 IDENTITY(INT, 1, 1) AS n INTO #Nums 3 FROM master.dbo.syscolumns sc1 4   5 INSERT INTO TestTable (Col2, Col3) 6 SELECT 2, REPLICATE('x', 2000) FROM #nums 7 DROP TABLE #nums 8 GO 9  10 -- Check the activity in TempDb before we execute the sort operation.11 SELECT num_of_writes, num_of_bytes_written FROM12 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1)13 GO14  15 -- SQL Server has now accurate statistics and estimates 801 rows for the sort operator.16 -- SQL Server requests a memory grant of 6.656kb, which is now enough.17 -- SQL Server now spills the sort operation not to TempDb.18 -- Logical reads: 57719 DECLARE @x INT20  21 SELECT @x = Col2 FROM TestTable22 WHERE Col2 = 223 ORDER BY Col324 GO25  26 -- Check the activity in TempDb after the execution of the sort operation.27 -- There is now no activity in TempDb during the previous SELECT statement.28 SELECT num_of_writes, num_of_bytes_written FROM29 sys.dm_io_virtual_file_stats(DB_ID('tempdb'), 1)30 GO

嗯,這是個非常簡單的例子,向你展示在SQL Server內部如何產生Sort Warning,其實一點也不神秘!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品av电影| 亚洲图片在区色| 欧美激情视频一区| 日本伊人精品一区二区三区介绍| 亚洲成人av片在线观看| 成人免费视频在线观看超级碰| 在线视频国产日韩| 97国产真实伦对白精彩视频8| 国产69精品久久久久久| 久久久成人的性感天堂| 欧美国产乱视频| 色偷偷偷亚洲综合网另类| 91视频免费网站| 日产精品99久久久久久| 狠狠躁天天躁日日躁欧美| 久久影院资源站| 国产亚洲精品日韩| 国产成人自拍视频在线观看| 一区二区在线视频播放| 日日骚av一区| 日韩毛片在线观看| 国内精品国产三级国产在线专| 国产一区二区久久精品| 97超碰蝌蚪网人人做人人爽| 欧美日韩精品在线观看| 欧美激情久久久久久| 日韩高清有码在线| 91情侣偷在线精品国产| 亚洲亚裔videos黑人hd| 欧美性猛交xxxx黑人猛交| 色噜噜狠狠狠综合曰曰曰| 亚洲国产欧美日韩精品| 91国产视频在线播放| 少妇精69xxtheporn| 国产精品久久久久久av福利软件| 欧美性高跟鞋xxxxhd| 欧美刺激性大交免费视频| 在线观看日韩欧美| 久久久91精品| 亚洲人永久免费| 91香蕉电影院| 欧美成人中文字幕在线| 一区二区三区四区精品| 亚洲精品女av网站| 国产999精品久久久| 欧美性一区二区三区| 欧美精品video| 亚洲人成网站在线播| 成人午夜在线观看| 韩国19禁主播vip福利视频| 欧美国产极速在线| 91精品国产91| 97免费在线视频| 亚洲精品综合久久中文字幕| 国产亚洲精品久久久久久牛牛| 欧洲成人性视频| 国产91对白在线播放| 青草成人免费视频| 国产亚洲精品成人av久久ww| 国产精品女主播视频| 国产成人精品av在线| 亚洲欧美在线播放| 国产精品嫩草影院久久久| 欧美激情a在线| 亚洲最新视频在线| 一本色道久久88综合日韩精品| 国产一区红桃视频| 正在播放欧美一区| 中文一区二区视频| 国产成人一区二区三区电影| 国产精品电影在线观看| 欧美另类在线观看| 在线视频欧美性高潮| 亚洲精品av在线| 午夜精品在线观看| 黄色成人在线免费| 成人性生交大片免费看视频直播| 亚洲天堂色网站| 视频在线观看一区二区| 国产亚洲免费的视频看| 综合激情国产一区| 精品国产一区二区三区久久久狼| 亚洲va欧美va在线观看| 国产精品一香蕉国产线看观看| 欧美国产视频日韩| 午夜精品久久久久久久久久久久久| 97在线观看视频| 欧日韩在线观看| 亚洲一区二区三区sesese| 国产精品丝袜高跟| 91精品国产高清自在线看超| 在线亚洲男人天堂| 激情亚洲一区二区三区四区| 欧美成人精品在线观看| 日韩av123| 亚洲午夜未删减在线观看| 成人美女av在线直播| 国产一区二区丝袜高跟鞋图片| 91久久精品国产91久久性色| 国产精品久久久久久久久久久久| 91香蕉亚洲精品| 久久午夜a级毛片| 国产精品中文字幕在线观看| 久久亚洲综合国产精品99麻豆精品福利| 中国人与牲禽动交精品| 国产精品网站视频| 欧美在线播放视频| 91在线视频精品| 亚洲免费电影在线观看| 国产亚洲精品久久| 国产精品一二三视频| 国产亚洲激情视频在线| 亚洲石原莉奈一区二区在线观看| 久久久久久久久久久成人| 亚洲精品国产福利| 成人女保姆的销魂服务| 7m第一福利500精品视频| 国产精品高精视频免费| 欧美寡妇偷汉性猛交| 亚洲www在线| 精品视频—区二区三区免费| 欧美性生交大片免网| 久久久久在线观看| 久久在线观看视频| 91高清免费视频| 97欧美精品一区二区三区| 国产精品av电影| 日韩成人中文电影| 亚洲图片制服诱惑| 日韩国产精品亚洲а∨天堂免| 日韩精品在线影院| 亚洲free嫩bbb| 欧美色视频日本版| 亚洲天堂成人在线视频| 久久人人97超碰精品888| 欧美激情欧美狂野欧美精品| 久久成人精品一区二区三区| 国产精品27p| 57pao成人永久免费视频| 亚洲人成电影网站色www| 亚洲91av视频| 国产一区二区在线免费视频| 久久国产精品久久久久久| 九九久久久久久久久激情| 深夜精品寂寞黄网站在线观看| 亚洲午夜久久久久久久| 亚洲另类欧美自拍| 欧美激情免费观看| 福利视频第一区| 粗暴蹂躏中文一区二区三区| 欧美另类暴力丝袜| 日韩精品久久久久久久玫瑰园| 亚洲色图综合久久| 日韩视频免费观看| 欧美激情一区二区三区成人| 久久成人一区二区| 久久人人爽人人爽人人片av高清| 亚洲国产成人精品女人久久久| 欧美日韩国产精品一区二区三区四区| 日韩视频免费在线观看| 国产精品久久久久免费a∨| 国产一区二区三区视频免费| 欧美日韩另类视频| 91国内产香蕉|