【发布时间】:2019-03-04 17:18:13
【问题描述】:
我有一个存储过程,它执行一个查询并将该行返回到如下变量中:
SELECT @item_id = I.ID, @label_ID = SL.label_id,
FROM tb_A I
LEFT JOIN tb_B SL ON I.ID = SL.item_id
WHERE I.NUMBER = @VAR
我有一个 IF 来检查 @label_ID 是否为空。如果为空,则进入 INSERT 语句,否则进入 UPDATE 语句。让我们专注于插入我知道我遇到问题的地方。 INSERT 部分如下:
IF @label_ID IS NULL
BEGIN
INSERT INTO tb_B (item_id, label_qrcode, label_barcode, data_leitura, data_inclusao)
VALUES (@item_id, @label_qrcode, @label_barcode, @data_leitura, GETDATE())
END
因此,tb_B 在 ID 列中有一个 PK,在 item_ID 列中有一个 FK,它引用 tb_A 表中的列 ID。
我运行了 SQL Server Profiler,发现有时此存储过程的持续时间约为 2300 毫秒,而正常平均时间为 16 毫秒。
我运行了“执行计划”,最大的成本在“聚集索引插入”组件中。如下图:
有关表格的更多详细信息:
tb_A Storage:
Index space: 6.853,188 MB
Row count: 45988842
Data space: 5.444,297 MB
tb_B Storage:
Index space: 1.681,688 MB
Row count: 15552847
Data space: 1.663,281 MB
Statistics for INDEX 'PK_tb_B'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name Updated Rows Rows Sampled Steps Density Average Key Length String Index
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PK_tb_B Sep 23 2018 2:30AM 15369616 15369616 5 1 4 NO 15369616
All Density Average Length Columns
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6.506343E-08 4 id
Histogram Steps
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 0 1 0 1
8192841 8192198 1 8192198 1
8270245 65535 1 65535 1
15383143 7111878 1 7111878 1
15383144 0 1 0 1
Statistics for INDEX 'IDX_tb_B_ITEM_ID'.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Name Updated Rows Rows Sampled Steps Density Average Key Length String Index
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IDX_tb_B_ITEM_ID Sep 23 2018 2:30AM 15369616 15369616 12 1 7.999424 NO 15369616
All Density Average Length Columns
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6.50728E-08 3.999424 item_id
6.506343E-08 7.999424 item_id, id
Histogram Steps
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 2214 0 1
16549857 0 1 0 1
29907650 65734 1 65734 1
32097131 131071 1 131071 1
32296132 196607 1 196607 1
32406913 98303 1 98303 1
40163331 7700479 1 7700479 1
40237216 65535 1 65535 1
47234636 6946815 1 6946815 1
47387143 131071 1 131071 1
47439431 31776 1 31776 1
47439440 0 1 0 1
是否有任何最佳实践可供我应用并使此执行持续时间稳定?
希望你能帮助我!!! 提前谢谢...
【问题讨论】:
-
我怀疑插入本身就是问题所在。一般来说,短期阻塞或服务器资源的可能性更大。否则,我希望持续时间一致。
-
这是访问表 tb_B 的唯一进程...但表 tb_A 用于其他进程。在哪里可以查看服务器资源是否正常?
-
由于在参考约束检查期间锁定在 tbl_A 或 tbl_A 行上,也可能发生阻塞。我不能具体说明好与否,但一般的方法是在好时和坏时进行监控。例如,插入期间的大型查询可能会使用过多的 CPU、内存和磁盘,从而导致该期间的插入速度变慢。
-
takes around 2300ms哪个语句需要这么多?您知道,分析器允许跟踪单独的语句。关于执行计划:insert是使用此语句执行的唯一操作。而你担心“90%”? a) 它是您正在执行的唯一命令 b) 它几乎是零执行时间的 90%。统计在这里毫无意义。您最好向我们展示文件增长设置。而 2s 更可能是锁定问题。 -
您的页面丰满度很高。如果您的应用程序执行大量插入,请尝试设置较小的填充因子。阅读:brentozar.com/archive/2013/04/five-things-about-fillfactor
标签: sql-server tsql indexing insert sql-execution-plan