gpt4 book ai didi

sql-server - 用索引更新表太慢

转载 作者:行者123 更新时间:2023-12-03 23:14:31 26 4
gpt4 key购买 nike

我在我们应用程序的实时系统上观察 Profiler,我看到有一条我们定期(每秒)运行的更新指令非常慢。每次大约需要 400 毫秒。查询包括此更新(这是缓慢的部分)

UPDATE BufferTable
SET LrbCount = LrbCount + 1,
LrbUpdated = getdate()
WHERE LrbId = @LrbId

这是表格

CREATE TABLE BufferTable(
LrbId [bigint] IDENTITY(1,1) NOT NULL,
...
LrbInserted [datetime] NOT NULL,
LrbProcessed [bit] NOT NULL,
LrbUpdated [datetime] NOT NULL,
LrbCount [tinyint] NOT NULL,
)

该表有 2 个索引(非唯一索引和非聚集索引),字段按以下顺序排列:
* Index1 - (LrbProcessed, LrbCount)
* Index2 - (LrbInserted, LrbCount, LrbProcessed)

当我看到这个时,我认为问题可能来自 Index1,因为 LrbCount 变化很大,它改变了索引中数据的顺序。
但是在停用 index1 之后,我看到查询所花的时间与最初相同。然后我重建了index1并停用了index2,这次查询非常快。

在我看来 Index2 应该更新得更快,数据的顺序不应该改变,因为 LrbInserted 时间没有改变。

有人能解释一下为什么 index2index1 更难更新吗?

谢谢!

编辑

我刚刚意识到我的假设是错误的。
完整的查询还有另一部分负责延迟:

DECLARE @LrbId as bigint
SELECT TOP 1 @LrbId = LrbId
FROM Buffertable
WHERE LrbProcessed = 0
AND LrbCount < 5
ORDER BY LrbInserted

所以,这很可能与 Sql 引擎对使用哪个索引的错误决定有关。
对困惑感到抱歉。我想我们可以结束这个问题了。

最佳答案

Can someone explain why index2 is much heavier to update then index1?

index2 长得多: key 大小是 10 字节 (8 + 1 + 1) 而不是 2 (1 + 1)

可能它不适合缓存,需要页面查找来定位记录。

你的 table 有多大?

您可能还想启用 I/O 统计信息:

SET STATISTICS IO ON

,运行查询几次并在输出中查看物理页面读取数。

更新:

对于这个查询:

SELECT TOP 1 @LrbId = LrbId
FROM Buffertable
WHERE LrbProcessed = 0
AND LrbCount < 5
ORDER BY
LrbInserted

为了快速工作,创建以下索引:

CREATE INDEX ix_buffertable_p_c_i ON BufferTable (LrbProcessed, lrbCount, LrbInserted)

并重写查询:

WITH    cts (cnt) AS
(
SELECT 1
UNION ALL
SELECT cnt + 1
FROM cts
WHERE cnt < 5
)
SELECT TOP 1 bt.*
FROM cts
CROSS APPLY
(
SELECT TOP 1 bti.*
FROM BufferTable bti
WHERE LrbProcessed = 0
AND LrbCount = cts.cnt
ORDER BY
LrbInserted
) bt
ORDER BY
LrbInserted

关于sql-server - 用索引更新表太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2524234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com