gpt4 book ai didi

sql - SQL Server 2008+聚集索引的排序顺序

转载 作者:行者123 更新时间:2023-12-04 10:38:51 25 4
gpt4 key购买 nike

SQL Server 2008+聚集索引的排序顺序是否会影响插入性能?

在特定情况下,数据类型为integer,插入的值升序(Identity)。因此,索引的排序顺序将与要插入的值的排序顺序相反。

我的猜测是,它将产生影响,但是我不知道,也许SQL Server在这种情况下进行了一些优化,或者其内部数据存储格式对此无动于衷。

请注意,问题是关于INSERT的性能,而不是SELECT

更新资料
要更清楚地了解这个问题:如果将要插入的值(integer)与聚簇索引(ASC)的顺序相反(DESC),会发生什么?

最佳答案

它们是有区别的。不按簇顺序插入会导致大量碎片。

当您运行以下代码时,DESC聚集索引将在NONLEAF级别上生成其他UPDATE操作。

CREATE TABLE dbo.TEST_ASC(ID INT IDENTITY(1,1) 
,RandNo FLOAT
);
GO
CREATE CLUSTERED INDEX cidx ON dbo.TEST_ASC(ID ASC);
GO

CREATE TABLE dbo.TEST_DESC(ID INT IDENTITY(1,1)
,RandNo FLOAT
);
GO
CREATE CLUSTERED INDEX cidx ON dbo.TEST_DESC(ID DESC);
GO

INSERT INTO dbo.TEST_ASC VALUES(RAND());
GO 100000

INSERT INTO dbo.TEST_DESC VALUES(RAND());
GO 100000


这两个Insert语句产生的执行计划完全相同,但是当查看操作统计信息时,它们的差异与[nonleaf_update_count]相对。

SELECT 
OBJECT_NAME(object_id)
,*
FROM sys.dm_db_index_operational_stats(DB_ID(),OBJECT_ID('TEST_ASC'),null,null)
UNION
SELECT
OBJECT_NAME(object_id)
,*
FROM sys.dm_db_index_operational_stats(DB_ID(),OBJECT_ID('TEST_DESC'),null,null)


当SQL使用针对IDENTITY运行的DESC索引时,还有一个幕后操作。
这是因为DESC表变得碎片化(行插入在页面的开头),并且发生了其他更新来维护B树结构。

关于此示例,最值得注意的是DESC聚集索引的碎片化程度超过99%。 This is recreating the same bad behaviour as using a random GUID for a clustered index.
下面的代码演示了碎片。

SELECT 
OBJECT_NAME(object_id)
,*
FROM sys.dm_db_index_physical_stats (DB_ID(), OBJECT_ID('dbo.TEST_ASC'), NULL, NULL ,NULL)
UNION
SELECT
OBJECT_NAME(object_id)
,*
FROM sys.dm_db_index_physical_stats (DB_ID(), OBJECT_ID('dbo.TEST_DESC'), NULL, NULL ,NULL)


更新:

在某些测试环境中,我还发现随着[page_io_latch_wait_count]和[page_io_latch_wait_in_ms]的增加,DESC表将经受更多的等待。

更新:

关于SQL可以执行向后扫描时降序索引的意义已经引起了一些讨论。请阅读有关 limitations of Backward Scans的文章。

关于sql - SQL Server 2008+聚集索引的排序顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41299389/

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