SQL Server 超时:删除并重新创建索引解决了问题

4 index sql-server-2008

在我们的一个查询出现 sql 超时问题之后,我们添加了一些索引,然后使查询运行得非常快,并摆脱了我们遇到的任何超时问题。奇怪的是,使用大约一个月后,查询再次开始超时。如果我们删除相同的索引集并重新创建它们,查询将再次开始快速运行。

指数没什么特别的:

CREATE NONCLUSTERED INDEX [IX_Transaction_BillingAccountId] ON [dbo].[Transaction] 
(
     [BillingAccountId] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

关于为什么会发生这种情况的任何想法?我们使用的是 SQL Server 2008 Express。

Par*_*ram 6

索引可能存在碎片问题。

检查索引碎片的可能性 -

这是一个简单的查询来检查现有索引上的碎片:

DECLARE @DBNAME VARCHAR(130);
SET @DBNAME = 'MYDBNAME';

DECLARE @DBID INT;
SET @DBID = DB_ID(@DBNAME);

SELECT
OBJECT_ID AS objectID
, index_id AS indexID
, avg_fragmentation_in_percent AS fragmentation
, page_count 
INTO #indexDefragList
FROM
sys.dm_db_index_physical_stats 
(@DBID, NULL, NULL , NULL, N'Limited')
WHERE
index_id > 0
OPTION (MaxDop 1);

SELECT
i.[name] as indexname,
d.fragmentation,
d.page_count
FROM
#indexDefragList d
INNER JOIN sys.indexes i
ON d.objectid = i.object_id
ORDER BY 
d.fragmentation DESC

DROP TABLE #indexDefragList
Run Code Online (Sandbox Code Playgroud)

这将返回当前数据库中所有索引的列表,其碎片以 % 为单位。

重建索引将解决问题。

任何版本的 Microsoft SQL Server 都不支持自动重建索引 - 原因是重建索引可能是非常昂贵的操作,因此需要仔细安排和规划。

在许多环境中,将编写特殊脚本来处理此问题,例如:

http://weblogs.sqlteam.com/tarad/archive/2008/09/03/Defragmenting-Indexes-in-SQL-Server-2005.aspx

请注意,虽然 SQL 可以在许多情况下自动为您更新统计信息,但通过更仔细地管理这些信息也可以获得性能提升。

您可以轻松构建脚本以自动重建或重新组织它们。SQLFool有一篇很棒的文章,包括一个完整的预制脚本。

参考链接