f44*_*ran 4 performance sql-server insert performance-tuning
我有一个存储过程,它在几个表中插入一些记录。至少在几个表中,插入的记录数为 10000+。不过不超过15K。注意到3-5 mins
这个程序来完成。也可以从多个用户会话中调用相同的过程,这会导致某些会话等待 20 分钟才能获得响应。我能做些什么来减少这个时间吗?
数据库恢复模式是完整的(无法更改),因此根据我的理解 sqlBulkCopy 在这里没有帮助。很想听听您对此的看法。
该表包含 15 列。其中5列是该表的外键。没有标识列,而是所有 5 个外键列组合的聚集索引。我在其他关键列上有几个索引。其余的列是十进制和 varchar(50)。不过我确实有一个 varchar(max) 列。
尝试获取查询或查询相同以供您参考。查询中最昂贵操作 (54) 的屏幕截图:
如果表的聚集索引是列组合而不是标识列,插入会受到影响吗?
基本上查询是'insert into this_table select from this table join with 5个其他表,这些表的主键是外键,以更新这些值。联接都在表之间的键上。我不介意发布查询,但是您是否还需要查询中涉及的所有表的架构?
EDIT2: 首先感谢你们所有人的回答、评论和想法。从中发生读取的对象结果是一个没有聚集索引的堆。修改它确实显着改善了读取操作,从而改善了整体。
我将 David Spillet 的答案标记为已接受,因为它提供了一种解决问题的有条理的方法。学到了一些关于发布问题的知识:)
也感谢飞盘的评论和回答。我知道我一直在修改问题:)
如果没有关于过程[1]和它插入的表的更多细节,我们无法提供任何具体的帮助。一些一般性建议:
[1] 如果它是“绝密”,所以你不能直接包含代码[2]或(如果它很长)通过 pastebin 或类似的,那么也许是经过消毒的版本?
[2]但如果它是绝密的,也许你应该支付的顾问,而不是在公众要求免费咨询;-)
更新
发布的查询计划确实表明对于该特定语句,您有读取问题而不是写入问题。看起来您有一个相关的子查询,它为每行提供一个聚合图,并且没有合适的索引可供过滤(尽管有一个可以避免额外的排序操作,因此索引扫描不是其次是排序)。不仅如此(无论如何,这是有根据的猜测)我不能说没有已经要求的细节。对于这个具体的语句:语句54的SQL和“object8”和“object9”的表+索引结构,最好不要混淆[3]。
[3] 通过伪装名称,您可以隐藏一些可能为我们提供有关您实际尝试实现的目标的线索的信息。帮助我们为您提供帮助,提供所要求的详细信息,除非您确实需要,否则不要主动隐藏详细信息。
关于成本百分比
正如 Aaron 所说,成本百分比基于近似值90 年代后期 Microsoft 开发人员 PC 的特定配置的时代。即便如此,它们也不打算作为估计/指标和 IIRC 以外的任何东西,计算也没有因 CPU 和内存技术的变化而受到影响。计算也适用于逻辑操作:它们不区分在内存中执行的工作和物理 IO 操作。也要小心地考虑查询的其余部分,而不仅仅是那个昂贵的块 - 可能是由于在其他地方错过了优化而造成的费用,这导致否则有效的操作将运行数百万次而不是几次或仅运行一 - 成本 % 可能会导致您尝试优化该部分,而实际上核心问题仅几步之遥。