Sqlserver In 提示查询处理器耗尽了资源
Posted ZGJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sqlserver In 提示查询处理器耗尽了资源相关的知识,希望对你有一定的参考价值。
最近项目出了一个问题,经过排查发现是使用in语句子查询过多的话会出现查询处理器耗尽了资源,如果改为使用关联表是一个办法,但是在为了最小改动,改为使用exists实现
1、新建一个函数,注意:不是存储过程
ALTER FUNCTION [dbo].[dnt_split] ( @splitstring varchar(max), @separator CHAR(1) = ‘,‘ ) RETURNS @splitstringstable TABLE ( [item] VARCHAR(200) ) AS BEGIN DECLARE @currentindex INT DECLARE @nextindex INT DECLARE @returntext VARCHAR(200) SELECT @currentindex=1 WHILE(@currentindex<=datalength(@splitstring)) BEGIN SELECT @nextindex=charindex(@separator,@splitstring,@currentindex) IF(@nextindex=0 OR @nextindex IS NULL) SELECT @nextindex=datalength(@splitstring)+1 SELECT @returntext=substring(@splitstring,@currentindex,@nextindex-@currentindex) INSERT INTO @splitstringstable([item]) VALUES(@returntext) SELECT @currentindex=@nextindex+1 END RETURN END
2、修改In语句如下
StringBuilder ins = new StringBuilder(); //ins.Append("("); ins.Append("12,13");//ins.Append(")"); //未修改前下面直接 in + ins.ToString()即可,修改后改为
string strFilter = "exists(SELECT * from dnt_split(‘"+ ins.ToString()+ "‘, ‘,‘) where item = xxxid)";
直接将原来的in字句替换成strExist1即可。
3、为什么in语句会出现问题
原因在于in语句相当于将主表个子表做了笛卡尔积,系统资源不足的话,就会出问题,(实际中,我的另一台性能较好电脑不存在这个问题)。
4、其他关于in与exists
转自:https://zhidao.baidu.com/question/134174568.html
当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用。in 和 exists的区别如下:
4.1、运用情况不同
sql中in适用于子查询得出的结果集记录较少,主查询中的表较大且又有索引的表,。sql中exist适用于外层的主查询记录较少,子查询中的表大,又有索引的时候。
4.2、驱动顺序不同
IN是先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。exists是以外层表为驱动表,先被访问。
4.3、对NULL值处理不同。
IN不对NULL进行处理,exists会对NULL值进行处理。
4.4、底层原理不同
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
以上是关于Sqlserver In 提示查询处理器耗尽了资源的主要内容,如果未能解决你的问题,请参考以下文章
解决tail命令提示“tail: inotify 资源耗尽,无法使用 inotify 机制,回归为 polling 机制”