SQL SERVER 临时表导致存储过程重编译(recompile)的一些探讨_MySQL
SQLSERVER为了确保返回正确的值,或者处于性能上的顾虑,有意不重用缓存在内存里的执行计划,而重新编译执行计划的这种行为,被称为重编译(recompile)。那么引发存储过程重编译的条件有哪一些呢?下面罗列了一些导致重编译(recompile)的条件:
- 对查询所引用的表或视图进行更改(ALTER TABLE 和 ALTER VIEW)。
- 对执行计划所使用的任何索引进行更改。
- 对执行计划所使用的统计信息进行更新,这些更新可能是从语句(如 UPDATE STATISTICS)中显式生成,也可能是自动生成的。
- 删除执行计划所使用的索引。
- 显式调用 sp_recompile。
- 对键的大量更改(其他用户对由查询引用的表使用 INSERT 或 DELETE 语句所产生的修改)。
- 对于带触发器的表,插入的或删除的表内的行数显著增长。
- 使用 WITH RECOMPILE 选项执行存储过程。
- 有些DBCC FREEPROCCACHE;分离、附加数据库、数据升级也会清除内存里缓存的执行计划
好了,切入到今天我们要关注的问题:临时表的数据变化导致存储过程重编译问题,其实临时表的数据变化导致存储过程重编译实质上是因为临时表的数据变化,导致了临时表统计信息的自动更新,从而引起的重编译。那么触发临时表的统计信息的更新的条件或阀值是什么呢?说来也简单,就是下面一个这个公式(n表示变更前临时表的数据记录数,确切的说是上一次采集统计信息时临时表的记录数)
Temporary table
If n
If 6
If n > 500, RT = 500 + 0.20 * n.
有个网友说存储过程中的临时表数据变更的阀值有问题:他的原话如下
If n
If 6
上面这两个区间没有问题。但是大于500的之后,根本就不是变化大于20%之后再重编译。看了他提出的问题,其实我也不是特肯定,毕竟没有实际验证过。实践才是检验整理的唯一标准,那么我们就开始做实验吧,首先准备一下测试环境(Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64) ).脚本如下所示:
USE MyDBA; GO IF EXISTS(SELECT 1 FROM sys.sysobjects WHERE id=object_id(N'[dbo].[TEST]') AND OBJECTPROPERTY(id, N'IsTable')=1 ) BEGIN DROP TABLE dbo.TEST; CREATE TABLE TEST ( ID INT IDENTITY(1, 1) , NAME VARCHAR(40) , CONSTRAINT PK_TEST PRIMARY KEY(ID) ) END GO INSERT INTO TEST VALUES(NEWID()) GO 10000 CREATE PROCEDURE Usp_Recompile_TEST(@Index INT) AS BEGIN CREATE TABLE #T(ID INT , NAME VARCHAR(40)); INSERT INTO #T SELECT ID, NAME FROM TEST WHERE ID <=@Index; SELECT m.* FROM #T m INNER JOIN TEST n ON m.ID = n.ID END GO
准备好测试环境后,那么此时我们打开SQL Server工具SQL Server Profiler,选择“SP:Recompile”和“SP:Complete”事件,然后取消一些选择列,仅仅选择一些需要的列,例如 EventClass、TextData等。如下所示
开启Profile跟踪后,我们打开一个会话窗口,勾选“包括实际的执行计划”,然后再窗口执行下面SQL语句
EXEC dbo.Usp_Recompile_TEST 1;
如下所示,实际的执行计划中,我们看到“估计行数”和“实际行数”是一致的。
EXEC dbo.Usp_Recompile_TEST 2;
EXEC dbo.Usp_Recompile_TEST 6;
执行上面两个语句,我们会发现“估计行数”与“实际行数”开始出现偏差,因为数据库对临时表#T没有最新的统计信息,还是上一次收集的统计信息时的数据(1行数据)
EXEC dbo.Usp_Recompile_TEST 7; 此时已经触发了对临时表统计信息的采集更新(请见后面阐述)。
EXEC dbo.Usp_Recompile_TEST 130;
EXEC dbo.Usp_Recompile_TEST 500;
EXEC dbo.Usp_Recompile_TEST 506;
EXEC dbo.Usp_Recompile_TEST 507;
那么执行上面SQL语句,130我们确信不会导致临时表#T去更新统计信息,501会触发#T表的统计信息更新吗? 如果不会触发,那么确切的值是多少呢?答案是507,如下截图所示:
想必有些人会说,我实验的结果不一样哦(啪啦啪啦说一大堆),那么你是否真正的理解了下面公式呢? n表示临时表变跟前的记录数(确切的说是统计信息采集时的记录数),后面的RT表示变跟的记录数。
Temporary table
If n
If 6
If n > 500, RT = 500 + 0.20 * n.
由于我第一次执行的是EXEC dbo.Usp_Recompile_TEST 1,那么数据库的记录数为1,那么1+ 6 =7; 也就是上图EXEC dbo.Usp_Recompile_TEST 7时才触发临时表#T的统计信息更新,而为什么是507(7+500=507)呢,因为最后一次统计信息的采集,临时表#T的记录数为7 ,所以7+500=507,是否有点不解,那么你按我这个SQL执行一遍,然后用Profile跟踪、你会看到下面结果,如果还不太明白,结合截图好好理解一下:
DBCC FREEPROCCACHE;
EXEC dbo.Usp_Recompile_TEST 2;
EXEC dbo.Usp_Recompile_TEST 6;
EXEC dbo.Usp_Recompile_TEST 7;
EXEC dbo.Usp_Recompile_TEST 8;
如果还没有理解的话,我的表达能力已到极限了,自己再好好琢磨一下吧! 那么接下来才是我们重点想要验证、测试的。
DBCC FREEPROCCACHE;
EXEC dbo.Usp_Recompile_TEST 501;
此时临时表#T的记录数为501,那么当临时表#T里面的记录数变更了多少时,才会触发统计信息的更新呢? 由于是插入,那么根据公式应该是501 + (500 + 0.2*501) = 1101.2 ,那么应该是1101,即使是1100也不会变化。下面SQL Server Profile可以验证我们的推测
EXEC dbo.Usp_Recompile_TEST 1100;
EXEC dbo.Usp_Recompile_TEST 1101;
如果我们继续使用该存储过程,那么当参数为什么值时才会触发统计信息更新呢? 1101 +(500+0.2*1101)=1821.2,也就是说必须是1821才会触发统计信息更新,下面SQL Server Profile的截图也验证了我们的推测。
EXEC dbo.Usp_Recompile_TEST 1300;
EXEC dbo.Usp_Recompile_TEST 1320;
EXEC dbo.Usp_Recompile_TEST 1321;
EXEC dbo.Usp_Recompile_TEST 1820;
EXEC dbo.Usp_Recompile_TEST 1821;
所以综上述实验验证,SQL SERVER 临时表导致存储过程重编译(recompile)的那些阀值确实是正确的,也是没有问题的。当然如有疏漏或不对的地方,敬请指出。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

通用矩陣乘法(GeneralMatrixMultiplication,GEMM)是許多應用程式和演算法中至關重要的一部分,也是評估電腦硬體效能的重要指標之一。透過深入研究和優化GEMM的實現,可以幫助我們更好地理解高效能運算以及軟硬體系統之間的關係。在電腦科學中,對GEMM進行有效的最佳化可以提高運算速度並節省資源,這對於提高電腦系統的整體效能至關重要。深入了解GEMM的工作原理和最佳化方法,有助於我們更好地利用現代計算硬體的潛力,並為各種複雜計算任務提供更有效率的解決方案。透過對GEMM性能的優

7月29日,在AITO问界第四十万台新车下线仪式上,华为常务董事、终端BG董事长、智能汽车解决方案BU董事长余承东出席发表演讲并宣布,问界系列车型将于今年8月迎来华为乾崑ADS3.0版本的上市,并计划在8月至9月间陆续推送升级。8月6日即将发布的享界S9将首发华为ADS3.0智能驾驶系统。华为乾崑ADS3.0版本在激光雷达的辅助下,将大幅提升智驾能力,具备融合端到端的能力,并采用GOD(通用障碍物识别)/PDP(预测决策规控)全新端到端架构,提供车位到车位智驾领航NCA功能,并升级CAS3.0全

4月11日,華為官方首次宣布HarmonyOS4.2百機升級計劃,此次共有180餘款設備參與升級,品類覆蓋手機、平板、手錶、耳機、智慧螢幕等設備。過去一個月,隨著HarmonyOS4.2百機升級計畫的穩定推進,包括華為Pocket2、華為MateX5系列、nova12系列、華為Pura系列等多款熱門機型也已紛紛展開升級適配,這意味著會有更多華為機型用戶享受到HarmonyOS帶來的常用常新體驗。從使用者回饋來看,華為Mate60系列機種在升級HarmonyOS4.2之後,體驗全方位躍升。尤其是華為M

蘋果16系統中版本最好的是iOS16.1.4,iOS16系統的最佳版本可能因人而異添加和日常使用體驗的提升也受到了很多用戶的好評。蘋果16系統哪個版本最好答:iOS16.1.4iOS16系統的最佳版本可能因人而異。根據公開的消息,2022年推出的iOS16被認為是一個非常穩定且性能優越的版本,用戶對其整體體驗也相當滿意。此外,iOS16中新功能的新增和日常使用體驗的提升也受到了許多用戶的好評。特別是在更新後的電池續航力、訊號表現和發熱控制方面,使用者的回饋都比較正面。然而,考慮到iPhone14

1.使用最新版本的CodeIgniterCodeIgniter團隊會定期發布安全修補程式和更新來修復已知的漏洞。因此,確保你始終使用最新版本的CodeIgniter非常重要。你可以透過造訪CodeIgniter的官方網站來下載最新版本。 2.強制使用安全連線(HTTPS)https可以加密你的網站和使用者之間傳遞的數據,使其更難被惡意使用者截獲和竊取。你可以透過在你的伺服器上安裝SSL憑證來啟用HttpS。 3.避免使用預設配置CodeIgniter提供了許多預設配置來簡化開發過程。但是,這些預設配置可能並

Linux和Windows是兩種常見的作業系統,分別代表了開源的Linux系統和商業的Windows系統。在這兩種作業系統中,都存在著命令列介面,用於使用者與作業系統互動。在Linux系統中,使用者使用的是Shell命令列,而在Windows系統中,使用者使用的是cmd命令列。 Linux系統中的Shell命令列是一個非常強大的工具,可以完成幾乎所有的系統管理任

Oracle資料庫中修改系統日期方法詳解在Oracle資料庫中,修改系統日期的方法主要涉及修改NLS_DATE_FORMAT參數和使用SYSDATE函數。本文將詳細介紹這兩種方法及其具體的程式碼範例,幫助讀者更好地理解並掌握在Oracle資料庫中修改系統日期的操作。一、修改NLS_DATE_FORMAT參數方法NLS_DATE_FORMAT是Oracle數據

近日,華為宣布將於9月推出搭載玄璣感知系統的全新智慧穿戴新品,預計為華為的最新智慧手錶。該新品將整合先進的情緒健康監測功能,玄璣感知系統以其六大特性——準確性、全面性、快速性、靈活性、開放性和延展性——為用戶提供全方位的健康評估。系統採用超感知模組,優化了多通道光路架構技術,大幅提升了心率、血氧和呼吸速率等基礎指標的監測精度。此外,玄璣感知系統也拓展了以心率資料為基礎的情緒狀態研究,不僅限於生理指標,還能評估使用者的情緒狀態和壓力水平,並支持超過60項運動健康指標監測,涵蓋心血管、呼吸、神經、內分泌、
