如何解决INSERT SELECT 比 SELECT 慢
我在函数的一个简单部分遇到了一个大问题,它有一个返回类似 350 条记录的选择,我将结果插入到一个变量表中以供以后使用,但执行时间太长。
如果我只执行select,不执行insert,执行需要2秒。
DECLARE @CHEQUES2 TABLE (CardCode VARCHAR(20),Qtde Int,Total DECIMAL(16,2),Terceiro BIT,PRIMARY KEY (CardCode,Terceiro))
INSERT INTO @CHEQUES2 (CardCode,Qtde,Total,Terceiro)
SELECT CARDCODE,COUNT(Numero) Qtde,sum(VALOR) Total,EmTerceiro
FROM [VW_CP_teste] CHEQUES
WHERE STATUS = 0
GROUP BY CARDCODE,EmTerceiro
执行耗时30多分钟,但仅select只需要2秒
知道发生了什么吗?
我尝试使用 cte、subselect、cursor,从变量表中删除主键,但没有解决。
编辑:sql Server 2012,96GB RAM,2 Sockets Xeon 2630
Edit2:测试我知道如果我使用临时表或真实表,它会在 3 秒内执行。
Edit3:我所做的一切都很简单。此查询在函数内部使用,之所以是函数,是因为它用于连接表/视图,并且在许多其他查询中使用,例如在 Crystal Reports 中,因此将其更改为存储过程将是一个问题。
该功能不是新功能,问题是在我对 VW_CP_TESTE 进行了一些必要的更改并进行了更多连接之后才开始的。我知道问题从这里开始,但是对 VIEW 的整个搜索没有任何挣扎,只是将它与变量表一起使用的部分。它与变量表一起使用以获得性能,在使用之前“节省”一些资源。
解决方法
尽管您所做的一切看起来都很简单,但请尝试通过 #tempTableName 预选到 sql-server 临时表中。这些“#”临时表仅对当前会话/连接有效,并在连接完成后消失。如果您在存储过程中使用它,那么您将能够直接从中查询它。如果你仍然需要你的“声明”表实例,那么在 #temp... 之后插入一个类似
SELECT CARDCODE,COUNT(Numero) Qtde,sum(VALOR) Total,EmTerceiro
into #myTempTable
FROM [VW_CP_teste] CHEQUES
WHERE STATUS = 0
GROUP BY CARDCODE,EmTerceiro
DECLARE @CHEQUES2 TABLE (CardCode VARCHAR(20),Qtde Int,Total DECIMAL(16,2),Terceiro BIT,PRIMARY KEY (CardCode,Terceiro))
INSERT INTO @CHEQUES2 (CardCode,Qtde,Total,Terceiro)
select CardCode,EmTerciro from #myTempTable
也许它在插入之前在某处进行聚合时窒息,所以拉到它自己的#temp 将解决这个问题。如果时间仍然有问题,请告诉我。
备选方案
此外,如果您的函数在您准备时返回某种临时表结果,则存储过程也可以这样做。我在一个应用程序中有许多存储过程,我传递了一些参数来应用于查询,并且存储过程对#temp 表进行了大量预查询,解析,排序,进行其他清理工作。最后,我只做了一个
select * from #myResultCrud
并返回整个集合。只是一个您可能没有考虑过的选项。
,这似乎是我 2 天前遇到并问过的类似问题。
请查看这篇文章—— INSERT operation taking time for Table variable even for 0 rows
它通过使用临时表而不是表变量对我有用,但我知道您不能在这里使用临时表。
尝试使用我在帖子中提到的其他解决方法,即更改数据库兼容性级别。另外,您能否说出您的数据库的数据库兼容性级别。 您可以通过查询进行检查 -
SELECT COMPATIBILITY_LEVEL FROM sys.databases WHERE name = '{database name}';
并使用此查询进行更新 -
ALTER DATABASE {database name} SET COMPATIBILITY_LEVEL = 120;
根据我的经验,table 变量对于兼容性级别 的表现似乎非常糟糕
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。