SQL Server统计信息维护策略的选择_MySQL
问题描述:
在对OLTP系统的一个上千万的表做归档后,循环分批删除源表数据时,业务应用收到超时告警,如下:
V1.1.1.1: ****Process - QueryTransactionFor****: 23075129
Timeout expired.
The timeout period elapsed prior to completion of the operation or the server is not responding.
This failure occured while attempting to connect to the Principle server.
查询当前活跃进程,发现一个极慢的StatMan查询:
SELECT StatMan([SC0], [SC1], [SB0000]) FROM (SELECT TOP 100 PERCENT [SC0], [SC1], step_direction([SC0]) over (order by NULL) AS [SB0000] FROM (SELECT [TransactionID] AS [SC0], [ID] AS [SC1] FROM [dbo].[Product] TABLESAMPLE SYSTEM (8.340078e-001 PERCENT) WITH (READUNCOMMITTED) ) AS MS_UPDSTATS_TBL_HELPER ORDER BY [SC0], [SC1], [SB0000] ) AS MS_UPDSTATS_TBL OPTION (MAXDOP 1)
这是一个统计信息维护任务,来看看该表所有的统计信息。
EXEC sp_autostats 'dbo.Product';
GO
将结果集根据时间降序排列显示,如下:
[IX_Product_TransactinID] ON 2015-11-12 14:15:14 [IX_Product_CreateTime] ON 2015-11-12 10:17:50 [IX_Product_Number] ON 2015-10-23 12:10:51 [PK_Product] ON 2015-08-14 20:03:41 [_WA_Sys_0000000E_693CA210] ON 2015-07-03 10:39:36 [_WA_Sys_00000025_693CA210] ON 2014-12-05 16:22:20 [_WA_Sys_0000002A_693CA210] ON 2014-12-05 14:54:53 [_WA_Sys_0000000B_693CA210] ON 2014-07-01 10:52:54 [_WA_Sys_00000018_693CA210] ON 2013-01-24 02:16:11 [_WA_Sys_00000023_693CA210] ON 2012-12-20 13:17:27 [_WA_Sys_00000026_693CA210] ON 2012-12-20 13:17:26 [_WA_Sys_00000004_693CA210] ON 2012-12-20 13:17:25 [_WA_Sys_00000006_693CA210] ON 2012-12-20 13:17:24 [_WA_Sys_00000022_693CA210] ON 2012-12-20 13:17:23 [_WA_Sys_0000001B_693CA210] ON 2012-12-20 13:17:22 [_WA_Sys_0000001D_693CA210] ON 2012-12-20 13:17:21 [_WA_Sys_0000000F_693CA210] ON 2012-12-20 13:17:20 [_WA_Sys_00000013_693CA210] ON 2012-12-20 13:17:18
看到在当前时间点,索引[IX_Product_TransactinID]在更新统计信息。
在监控到StatMan进程的同时,也看到导致业务告警的一个查询极慢。
SELECT
p.[ID]
,p.[Name]
,p.[Price]
,p.[Amount]
,p.[TransactionID]
,t.[Action]
,t.[TransactionStatus]
,t.[TransactionResult]
FROM [Product] AS p LEFT JOIN [TransactionInfo] AS t ON p.[TransactionID] = t.[ID]
WHERE [TransactionID] = @transactionId
可以明确是因为删除Product表的数据,使得[TransactionID]列索引[IX_Product_TransactinID]达到了要更新统计信息的阈值,触发了索引维护。
问题处理:
为了让问题查询得到尽快恢复,我新建了一个[TransactionID]列索引,将[IX_Product_TransactinID]禁用,问题得到临时解决。
原理分析:
统计信息维护策略
当SQL Server需要去估算某个操作的复杂度时,它必定要试图去寻找相应的统计信息做支持。数据库管理员无法预估SQL Server会运行什么样的操作,所以也无法预估SQL Server可能会需要什么样的统计信息。如果靠人力来建立和维护统计信息,那将是一个非常复杂的工程。好在SQL Server不是这样设计的。在绝大多数情况下,SQL Server自己会很好地维护和更新统计信息,用户基本没有感觉,数据库管理员也没有额外的负担。
这主要是因为在SQL Server数据库属性里,有两个默认打开的设置:Auto Create Statistics和Auto Update Statistics。它们能够让SQL Server在需要的时候,自动建立要用到的统计信息,也能在发
现统计信息过时的时候,自动去更新它。
SQL Server会在什么情形下创建统计信息呢?主要有3种情况:
1.在索引创建时,SQL Server会自动地在索引所在的列上创建统计信息
所以从某种角度讲,索引的作用是双重的,它自己能够帮助SQL Server快速找到数据。而它上面的统计信息,也能够告诉SQL Server数据的分布情况。
2.管理员也可以通过CREATE STATISTICS之类的语句手动创建他认为需要的统计信息
如果打开了Auto Create Statistics,一般来讲很少需要手动创建。
3.当SQL Server想要使用某些列上的统计信息,发现没有的时候,“Auto Create Statistics”会让SQL Server自动创建统计信息。
例如,当语句要在某个(或者某几个)字段上做过滤,或者要拿它(们)和另外一张表做连接(Join),SQL Server要估算最后从这张表会返回多少条记录,这时候就需要一个统计信息的支持。如果没有,SQL Server会自动创建一个。
我们可以在SalesOrderHeader_test上试试。
sp_helpstats SalesOrderHeader_test
go
-- 返回表格没有statistics(索引上的除外)
select count(*) from
dbo.SalesOrderHeader_test
where OrderDate = '2004-06-11 00:00:00.000'
go
-- 运行一句在OrderDate上有过滤条件的查询
sp_helpstats SalesOrderHeader_test
go
-- 返回表格已经有了一个新的统计信息
statistics_name statistics_keys
------------------------------------------ ---------------
_WA_Sys_00000003_1A34DF26 OrderDate
因此,在打开Auto Create Statistics的数据库上,一般不需要担心SQL Server没有足够的统计信息来选择执行计划,这一点完全交给SQL Server管理就可以了。
SQL Server不仅要建立合适的统计信息,还要及时更新它们,使它们能够反映表格里数据的变化,数据的插入、删除、修改都可能会引起统计信息的更新。但是,更新统计信息本身也是一件消耗资源的事情,尤其是对比较大的表格。如果有一点点小的修改SQL Server都要去更新统计信息,可能SQL Server就得光忙活这个,来不及做其他事了。SQL Server还是要在统计信息的准确度和资源合理消耗之间做一个平衡。触发统计信息自动更新的条件是:
1.如果统计信息是定义在普通表格上的,那么当发生下面变化之一后,统计信息就被认为是过时的了,下次使用到时,会自动触发一个更新动作
(1)表格从没有数据变成有大于等于1条数据。
(2)对于数据量小于500行的表格,当统计信息的第一个字段数据累计变化量大于500以后。
(3)对于数据量大于500行的表格,当统计信息的第一个字段数据累计变化量大于500 + (20%×表格数据总量)以后。
所以对于比较大的表,只有1/5以上的数据发生变化后,SQL Server才会去重算统计信息。
2.临时表(Temp Table)上可以有统计信息,其维护策略基本和普通表格一致,但是表变量(Table Variable)上不能建统计信息
这样的维护策略能够保证花费比较小的代价,确保统计信息基本正确。本案例,反映这个维护策略在数据分布特殊的表格上,也有可能造成一些负面的影响,只需定期手工(或者做一个任务)更新表的统计信息即可。
在SQL Server 2005以后,数据库属性多了一个“Auto Update Statistics Asynchronously”。当SQL Server发现某个统计信息过时时,它会用老的统计信息继续现在的查询编译,但是会在后台启动一个任务,更新这个统计信息。这样下一次统计信息被使用到时,就已经是一个更新过的版本。这样做的缺点是不能保证当前这句查询的执行计划准确性,凡事有利有弊,数据库管理员可以根据实际情况做选择。
当然,的确有一些例外情况。由于数据的特殊性,会使得SQL Server这种Auto Update Statistics的算法不能满足确保执行计划准确性的需求,在实际使用中,有时候数据库的性能会突然之间慢下来。
有经验的管理员会安排做一次索引重建的任务,常常对性能会有所帮助。通常人们会解释为,因为索引重建消除了数据碎片,而提高了性能,其实索引重建还做了另外一件很重要的工作,它使用full scan的方式,重新更新了表上的统计信息,使得统计信息非常精确。这对性能帮助作用也会很大。
跟踪标记 2371
SQL Server 2008 R2 SP1介绍了一个非常好的特性,可以修改自动统计算法(auto stats algorithm),从默认的20%+500行到一个范围值(sliding scale)。该属性只能通过打开跟踪标记2371打开,而并不是默认打开的。
如果按自动统计算法一切运行良好,没有性能问题需要担心。现在只需要考虑到表基数太大像50000行或1000000时的阈值。在这种情况下,对于高基数的表,这些阈值可能不够好。例如,我有一个表基数为50000的表。我插入了20%(10000)新行。根据之前的标准阈值,这些20%的新插入的行不满足触发自动更新统计信息。这可能就是你的情况中性能问题的原因之一。如果你面对同样的问题,不需要担心,因为微软提供了跟踪标记2371.通过使用该标记,SQL Server对于自动更新超过25000行的表上的统计信息,将会决定动态的阈值。对于自动更新统计信息,更高的行基数将会使用更低的阈值。
2371:SQL根据需要自动修改统计信息更新的阀值,而不按照默认算法
http://www.sqlservergeeks.com/sql-server-trace-flag-2371/
策略选择
在大数据库上开启该跟踪标记,很明显是为了使用自动统计,因此需要打开自动统计。此外,我们需要对于拥有超级大表的数据库打开“Auto Update Statistics Asynchronously”。开启异步更新统计信息特性的原因是,当自动统计触发的时候,你不想看到查询超时。
我们知道自动统计当表中实际的行数改变时会更新统计信息。当超级大表触发了自动统计运行时,如果花费超过30秒运行更新统计信息命令,触发自动统计的查询语句将会超时,导致了事务回滚,意味着自动统计命令也回滚。因此下一个查询也会触发自动统计信息更新,并且这个过程将重复循环。
你会在SQL Server中随机看到查询超时,即使执行计划看起来总体正常。你也会看到存储该数据库的磁盘上产生了大量的IO,因为自动统计统计做了大量的表查询,并且自动统计不断循环运行。
当在数据库上开启异步自动更新统计信息,当自动统计被SQL Server触发时,查询不会等待更新统计信息命令去完成。而更新统计信息命令会在后台运行,让查询继续正常运行。现在查询将会使用旧的也许可用的统计信息运行,在这种情况下,它们在2秒之前可用,因此如果它们用于数秒也没有什么大不了。
不推荐在每个数据库上开启异步更新统计信息设置。所有的小数据库都会在超时时间内很好的更新统计信息。
对于需要开启异步更新统计信息的表,可以定时手动更新同步信息。
设置异步更新统计信息
SELECT name, is_auto_update_stats_on, is_auto_update_stats_async_on
FROM sys.databases
ALTER DATABASE YourDBName SET AUTO_UPDATE_STATISTICS_ASYNC ON
ALTER DATABASE YourDBName SET AUTO_UPDATE_STATISTICS ON
开启跟踪标记2371
USE master
GO
--以下示例以全局方式打开跟踪标记 2371。
DBCC TRACEON (2371 ,-1)
GO
DBCC TRACESTATUS (2371,-1)
GO
其他操作参考如下:
UPDATE STATISTICS
https://msdn.microsoft.com/zh-cn/library/ms187348%28v=sql.105%29.aspx
sp_updatestats
https://msdn.microsoft.com/zh-cn/library/ms173804%28v=sql.105%29.aspx
sp_autostats
https://msdn.microsoft.com/en-us/library/ms188775.aspx
DBCC SHOW_STATISTICS
https://msdn.microsoft.com/en-us/library/ms174384.aspx
STATS_DATE
https://msdn.microsoft.com/zh-cn/library/ms190330%28v=sql.105%29.aspx
后续处理:
修改统计信息更新策略为AUTO_UPDATE_STATISTICS_ASYNC
执行归档删除
执行更新归档表统计信息
将统计信息更新策略修改为同步更新
开启跟踪标记2371
考虑到该库的实时性、业务准确性要求极高,在归档删除完成后,将策略改为同步更新,并开启跟踪标记2371让SQL Server动态决定更小的更新阈值。
若该库没有这么高的要求,可以考虑对拥有超级大表的库设置异步更新,归档删除后,更新该表统计信息,并创建维护作业定时更新该表统计信息。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Microsoft Word 문서는 저장 시 일부 메타데이터를 포함합니다. 이러한 세부 정보는 문서 작성 날짜, 작성자, 수정 날짜 등 문서 식별에 사용됩니다. 또한 문자 수, 단어 수, 단락 수 등과 같은 기타 정보도 있습니다. 다른 사람이 값을 알 수 없도록 작성자나 마지막 수정 정보 또는 기타 정보를 제거하려는 경우 방법이 있습니다. 이번 글에서는 문서 작성자와 최종 수정 정보를 제거하는 방법을 살펴보겠습니다. Microsoft Word 문서에서 작성자 및 마지막 수정 정보 제거 1단계 – 다음으로 이동

iOS 17에는 두 개의 iPhone을 터치하여 누군가와 연락처 정보를 교환할 수 있는 새로운 AirDrop 기능이 있습니다. NameDrop이라고 하며 작동 방식은 다음과 같습니다. 전화를 걸거나 문자를 보내기 위해 새로운 사람의 전화번호를 입력하는 대신, NameDrop을 사용하면 iPhone을 상대방의 iPhone 근처에 두기만 하면 연락처 정보를 교환하여 상대방이 귀하의 전화번호를 알 수 있습니다. 두 장치를 함께 놓으면 연락처 공유 인터페이스가 자동으로 나타납니다. 팝업을 클릭하면 개인의 연락처 정보와 연락처 포스터가 표시됩니다(iOS17의 새로운 기능인 자신의 사진을 사용자 정의하고 편집할 수도 있습니다). 이 화면에는 "수신만" 또는 응답으로 자신의 연락처 정보를 공유하는 옵션도 포함되어 있습니다.

시스템 정보 사용 시작을 클릭하고 시스템 정보를 입력합니다. 아래 이미지에 표시된 대로 프로그램을 클릭하기만 하면 됩니다. 여기에서는 대부분의 시스템 정보를 찾을 수 있으며, 그 중 하나는 그래픽 카드 정보입니다. 시스템 정보 프로그램에서 구성 요소를 확장한 다음 표시를 클릭합니다. 프로그램이 필요한 모든 정보를 수집하도록 하고, 준비가 되면 시스템에서 그래픽 카드별 이름과 기타 정보를 찾을 수 있습니다. 그래픽 카드가 여러 개 있더라도 여기에서 컴퓨터에 연결된 전용 및 통합 그래픽 카드와 관련된 대부분의 콘텐츠를 찾을 수 있습니다. 장치 관리자 사용 Windows 11 대부분의 다른 Windows 버전과 마찬가지로 장치 관리자에서 컴퓨터의 그래픽 카드를 찾을 수도 있습니다. 시작을 클릭한 다음

PHP 플래시 세일 시스템의 가격 전략 및 프로모션 디자인의 핵심 플래시 세일 시스템에서는 가격 전략과 프로모션 디자인이 매우 중요한 부분이다. 합리적인 가격 전략과 잘 설계된 프로모션은 사용자를 플래시 세일 활동에 참여하도록 유도하고 시스템의 사용자 경험과 수익성을 향상시킬 수 있습니다. 다음은 PHP 플래시 세일 시스템의 가격 전략 및 판촉 활동 설계의 핵심 사항을 자세히 소개하고 구체적인 코드 예제를 제공합니다. 1. 가격 전략 설계의 핵심: 기준 가격 결정: 플래시 세일 시스템에서 기준 가격은 제품이 정상적으로 판매될 때의 가격을 의미합니다. 존재하다

EXE에서 PHP로: 기능 확장을 위한 효과적인 전략 인터넷의 발전과 함께 더 많은 사용자 액세스와 더 편리한 작업을 위해 점점 더 많은 응용 프로그램이 웹으로 마이그레이션되기 시작했습니다. 이 과정에서 원래 EXE(실행 파일)로 실행되는 기능을 PHP 스크립트로 변환하려는 요구도 점차 늘어나고 있다. 이 기사에서는 기능 확장을 위해 EXE를 PHP로 변환하는 방법에 대해 설명하고 구체적인 코드 예제를 제공합니다. EXE를 PHP 크로스 플랫폼으로 변환하는 이유: PHP는 크로스 플랫폼 언어입니다.

현재 영상 3D 재구성 작업은 일반적으로 일정한 자연광 조건 하에서 여러 시점(멀티뷰)에서 대상 장면을 캡처하는 멀티뷰 스테레오 재구성 방식(Multi-view Stereo)을 사용합니다. 그러나 이러한 방법은 일반적으로 Lambertian 표면을 가정하므로 고주파수 세부 정보를 복구하는 데 어려움이 있습니다. 장면 재구성에 대한 또 다른 접근 방식은 고정된 시점에서 캡처한 이미지를 다양한 포인트 라이트로 활용하는 것입니다. 예를 들어 포토메트릭 스테레오 방법은 이 설정을 사용하고 해당 음영 정보를 사용하여 램버시안 개체가 아닌 개체의 표면 세부 정보를 재구성합니다. 하지만 기존의 싱글뷰 방식에서는 눈에 보이는 것을 표현하기 위해 보통 노멀맵이나 깊이맵을 사용하는 경우가 많습니다.

iOS17에는 아이폰 두 대를 동시에 터치해 누군가와 연락처 정보를 교환할 수 있는 새로운 에어드롭(AirDrop) 기능이 있다. NameDrop이라고 하며 실제 작동 방식은 다음과 같습니다. NameDrop을 사용하면 전화를 걸거나 문자를 보낼 때 새로운 사람의 전화번호를 입력할 필요가 없어 상대방이 귀하의 전화번호를 알 수 있습니다. iPhone을 상대방의 iPhone에 가까이 갖다 대기만 하면 연락처 정보를 교환할 수 있습니다. 두 장치를 함께 놓으면 연락처 공유 인터페이스가 자동으로 나타납니다. 팝업을 클릭하면 사람의 연락처 정보와 연락처 포스터(사용자 정의하고 편집할 수 있는 자신의 사진, iOS 17의 새로운 기능)가 표시됩니다. 이 화면에는 "수신 전용"도 포함되어 있거나 이에 대한 응답으로 자신의 연락처 정보를 공유할 수 있습니다.

WeChat의 정보 수신이 지연되는 이유는 네트워크 문제, 서버 부하, 버전 문제, 장치 문제, 메시지 전송 문제 또는 기타 요인 때문일 수 있습니다. 자세한 소개: 1. 네트워크 문제 WeChat의 정보 수신 지연은 네트워크 연결과 관련이 있을 수 있습니다. 네트워크 연결이 불안정하거나 신호가 약한 경우 휴대폰이 지연될 수 있습니다. 2. 서버 부하가 높을 때, 특히 바쁜 시간이나 많은 사용자가 WeChat을 사용할 때 정보 전송이 지연될 수 있습니다. 같은 시간 등등
