我可以在表中添加什么索引:
CREATE TABLE [WData](
[Account] [varchar](50) NOT NULL,
[Table] [varchar](50) NOT NULL,
[BatchID] [datetime2](7) NOT NULL,
[XmlRow] [xml] NULL
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
以便后续存储过程运行得更快?现在它很慢.
create PROCEDURE [Update_WData]
@Account VARCHAR(50),
@Table VARCHAR(50),
@BatchID DATETIME2,
@XmlRows xml
AS
BEGIN
SET NOCOUNT ON;
DECLARE @input TABLE (
[XmlRow] xml NULL
);
INSERT INTO @input (XmlRow)
SELECT
c1.query('.')
FROM @XmlRows.nodes('/Block/NewRow') AS t(c1);
DECLARE @output TABLE ([ACTION] NVARCHAR(50) );
MERGE WData AS t
USING @input AS s
ON (t.Account = @Account AND t.[Table]=@Table AND CONVERT(VARCHAR(max),t.XmlRow)=CONVERT(VARCHAR(max),s.XmlRow))
WHEN NOT MATCHED BY TARGET
THEN INSERT (Account,[Table],BatchID, [XmlRow])
VALUES (@Account, @Table, @BatchID, s.XmlRow )
WHEN MATCHED AND t.BatchID <> @BatchID
THEN UPDATE SET t.BatchID = @BatchID
OUTPUT
$ACTION
INTO @output;
SELECT [Action], COUNT(*) AS [Count]
FROM @Output
GROUP BY [Action]
END
Run Code Online (Sandbox Code Playgroud)
您还没有告诉我们您的群集密钥的选择性,但我认为由于您遇到了性能问题,因此存在多个具有重复值的行.
用于匹配来自@inputto的行的连接WData将是嵌套循环连接,并且WData在连接的内侧使用聚簇索引查找.估计来自的行数@input为1,因此SQL Server认为它需要一次执行范围查找操作,WData以找到比较XML列内容所需的所有行.
比方说,你有10000行的一个独特的组合Account,并[Table]和你的XML包含6级NewRow被粉碎为六行中的节点@Input.

聚集索引查找执行6次,每次返回10000行,然后比较连接中的XML列60000次.
您可以做的是添加一个计算的持久列,它是XML列的哈希值.
CREATE TABLE [WData](
[Account] [varchar](50) NOT NULL,
[Table] [varchar](50) NOT NULL,
[BatchID] [datetime2](7) NOT NULL,
[XmlRow] [xml] NULL,
H AS CAST(HASHBYTES('SHA2_512', CAST([XmlRow] AS VARBINARY(MAX))) AS BINARY(64)) PERSISTED
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
并且还将计算列添加到@Input.
DECLARE @input TABLE (
[XmlRow] XML NULL,
H AS CAST(HASHBYTES('SHA2_512', CAST([XmlRow] AS VARBINARY(MAX))) AS BINARY(64)) PERSISTED
);
Run Code Online (Sandbox Code Playgroud)
并使用列H中ON的条款MERGE声明.
ON (
t.Account = @Account AND
t.[Table]=@Table AND
t.H = s.H AND
CONVERT(VARCHAR(max),t.XmlRow)=CONVERT(VARCHAR(max),s.XmlRow)
)
Run Code Online (Sandbox Code Playgroud)
对于生成的哈希,您不太可能发生任何冲突(不同XML值的值相同),但哈希仅使用前8000个字节生成,因此您应保留XML列的原始比较.
修改完成后,您最终会得到此查询计划.

读取次数相同,因为Clustered Index Seek仍然执行6次,检查10000行.在查找中完成对哈希的检查作为残差谓词,使得运算符在这种情况下根本不返回任何行,因此在XML列上没有进行比较.
如果您不介意使用64字节扩展群集密钥,则还可以添加H密钥并大幅降低读取次数.在我的测试中,它从1261下降到62.
CREATE CLUSTERED INDEX IX_WData ON WData(Account, [Table], H)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
712 次 |
| 最近记录: |