Sql server 慢速插入:从视图中选择

Sql server 慢速插入:从视图中选择,sql-server,sql-insert,sql-view,Sql Server,Sql Insert,Sql View,以下语句至少需要4秒钟: INSERT INTO [SomeSmallTable] SELECT * FROM ComplexView WHERE [Date] = convert(datetime, '23/09/2020',103) 但是,如果只运行“选择零件”而不运行“插入”,则所需时间不到半秒: SELECT * FROM ComplexView WHERE [Date] = convert(datetime, '23/09/2020',103) 视图选择的行少于200行,而

以下语句至少需要4秒钟:

INSERT INTO [SomeSmallTable] 
SELECT * FROM ComplexView 
WHERE [Date] = convert(datetime, '23/09/2020',103)
但是,如果只运行“选择零件”而不运行“插入”,则所需时间不到半秒:

SELECT * 
FROM ComplexView 
WHERE [Date] = convert(datetime, '23/09/2020',103)
视图选择的行少于200行,而名为“SomeSmallTable”的表只包含几行。我认为这个问题始于我们更新了名为“ComplexView”的视图。ComplexView基于其他视图(其中一些视图基于其他视图本身)以及一些表

我尝试使用
sp\u refreshview
刷新所有视图,但没有效果

我们如何才能确定这个问题的原因并有希望解决它


[编辑]

我对一些评论的答复是:

  • @Dale K:我不能发布执行计划,我认为它们非常复杂,也不相关,因为它们对于两个语句都是相等的,无论是否有插入部分,除了表插入部分。但我确实看到了插入成本为100%。由于某些原因,SQL在将视图结果插入表时遇到问题

  • @Panagiotis Kanavos:除了我,没有人在使用数据库。这是我们客户数据库的副本,我正在本地机器上处理

  • @gotqn:SomeSmallTable是一个表,所以没有表变量或临时表。但是,它是在用户在应用程序中打开特定表单时创建的,然后被删除,然后用户关闭此表单

  • @Arvo:SomeSmallTable没有键和触发器。该视图返回的插入到该表中的行少于200行,在插入这些行之前,该表为空

  • 我遵循了公认答案中的步骤,最终将当前的“ComplexView”与以前的版本进行了比较,并找出了导致此问题的原因


  • 正如其他人所说,检查执行计划是第一步。鉴于
    插入(而不是查询)导致延迟,您可以进一步排除故障。以下是一些您可以尝试的东西:

    • 尝试使用统计IO了解更多信息,如回答的那样
    • 尝试使用静态数据进行
      插入
      (例如
      插入[SomeSmallTable]值(1、2、“…等”);
      )。这将告诉您问题是否是任何
      INSERT
      语句,或者是从特定视图插入时
    • 检查视图返回的数据量。4s可能合理,也可能不合理,这取决于插入的行数
    • 检查表的设计,查看它是如何使用主键、外键、复合键、索引、触发器等的。其中一些功能优化了表的选择设计,但作为一种折衷,插入速度会变慢。关于这一点,可以找到一个很好的答案
    • 如果您知道这不是一个负载问题(因为您是唯一使用此数据库的人),请检查是否有其他因素限制了您正在使用的计算机上的资源(其他资源密集型任务、同时发生的任何其他查询、SQL Server中的计划作业等),您可以使用这些因素实时查看查询
    • 如果缓慢的性能不限于此特定查询,那么您可以研究其他通用查询

    检查执行计划?把它们贴在这里?还有谁在用那张桌子?如果它被其他连接/事务锁定以供读取,则INSERT必须等待才能修改内容。在任何情况下,查询都不会按原样执行。它被编译成一个执行计划。这就是为什么在出现性能问题时应该始终检查执行计划的原因。
    [SomeSmallTable]
    什么是SQL表、表变量或临时表?您的
    SomeSmallTable
    是否有主键?它是否定义了触发器?我认为这是一种不错的故障排除方法。您可以尝试的另一个步骤是将插入拆分为两个步骤,例如,
    SELECT*into#attable FROM…
    ,然后
    insert into SomeSmallTable SELECT*FROM#attable
    。如果这一切正常,那么我怀疑这两个语句(SELECT和INSERT)之间的执行计划略有不同——特别是如果其中一个视图使用某个SmallTable。如果涉及多行,我还建议尝试从另一个源(例如CSV文件)进行
    批量插入。你说得对,临时表是另一种检查方法。@sbgib我不熟悉统计数据。我想我必须使用集合统计,所以我这样做了。对于视图查询的许多表,它会返回一些较高的扫描计数(最高:186)和逻辑读取(最高663到3635)值。对于1个表305,预读读取,另一个表1个物理读取。我还将记录插入到另一个表中,并将这些记录插入到“SomeSmallTable”中,这很快。因此,从视图插入速度较慢,从静态数据插入速度较快。该视图返回93行(217列!)。视图可能就是问题所在。问题与“ComplexView”中的更改有关,由于某种原因,该更改导致此视图在“SomeSmallTable”中插入缓慢。按照公认答案中的步骤帮助我找到了这个解决方案,特别是使用统计IO.Nice!:)很高兴听到你找到了原因!我自己对统计数据不太熟悉,也不得不这么做。听起来您能够解决“SomeSmallTable”的设计不能成为问题,因为静态数据和来自另一个表的数据可以快速插入。在任何情况下,“ComplexView”都是原因,这听起来像是更改视图设计是最严格的解决方案(例如更改联接、子查询的组合等)