Jax*_*ian 2 index sql-server azure-sql-database
我们有许多表(约 1M 条记录),其中有一列定义为:[GlobalID] [uniqueidentifier] NOT NULL
自动填充newid()
. 我们使用此 ID 跨多个系统、数据库、文件导入/导出等同步数据。
对于此列,我们创建了以下索引:
CREATE UNIQUE NONCLUSTERED INDEX [IxUx_XXXXXX_GlobalID] ON [dbo].[XXXXXX]
(
[GlobalID] ASC
)
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这个索引很快就会变得碎片化,所以我们必须保持重建。然而,这正是我们遇到问题的地方。我的维护脚本通过并重建超过 x% 碎片的所有索引ONLINE=ON
总是永远挂在这些索引上。当数据库几乎完全空闲时,我试图让一个运行超过 3 个小时而没有成功。只是为了踢球,我什至将数据库置于单用户模式,没有任何改变。我也试过ONLINE=OFF
, 再次没有改变。不过,我是能够简单地丢弃/创建索引,并将其〜15秒内完成!
为了确保我的维护脚本没有什么可笑的,我手动尝试重建这些索引但没有成功。我使用的脚本是:ALTER INDEX IxUx_XXXXXX_GlobalID ON [dbo].[XXXXXX] REBUILD WITH (ONLINE=ON)
它似乎永远不会成功。考虑到我可以在 15 秒内删除并重新创建它,3 小时对于在空闲数据库上看到成功来说已经绰绰有余了。
现在,我已经更改了我的维护脚本以过滤掉名称中带有“GlobalID”的索引,然后有一个删除/创建这些索引的后续脚本。直到我们开始对这些类型的列进行命名变体(即,我们需要一个 uniqueidentifier 用于其他目的)之前,我们一直在这样做。
知道为什么重建这些索引永远不会在合理的时间内完成吗?我看到这种情况发生在大约 12 个表中,所有表都具有基本相同的列/索引。
我的建议是:
(a) 与 Azure 支持人员交谈。这不是它应该如何工作 AFAIK。
(b) 在构建要重建/重组的索引列表时,向条件添加 NOT EXISTS 子句以消除任何以 GUID 作为前导键列的索引:
SELECT name, etc.
FROM sys.indexes AS i
INNER JOIN sys.dm_db_index_physical_stats AS s
ON ...
WHERE ... criteria ...
AND NOT EXISTS
(
SELECT 1 FROM sys.index_columns AS ic
INNER JOIN sys.columns AS c
ON ic.object_id = c.object_id
AND ic.column_id = c.column_id
AND ic.key_ordinal = 1 -- only leading column
AND c.system_type_id = 36 -- uniqueidentifer
WHERE ic.index_id = i.index_id
);
Run Code Online (Sandbox Code Playgroud)
(c) 在决定手动处理这些列之前,请等到它们确实给您带来性能问题,您可以证明并且不可否认地将此索引的碎片确定为问题。
(d) 或者,只使用 (b) 中的反向查询来始终执行手动删除/创建,而不是一遍又一遍地处理问题。
归档时间: |
|
查看次数: |
1119 次 |
最近记录: |