[英]How to improve performance of SQL query with parameters?
我正在使用SQL Server 2005。
我在执行这样的SQL语句时遇到问题
DECLARE @Param1 BIT
SET @Param1 = 1
SELECT
t1.Col1,
t1.Col2
FROM
Table1 t1
WHERE
@Param1=0 OR
(t1.Col2 in
(SELECT t2.Col4
FROM
Table2 t2
WHERE
t2.Col1 = t1.Col1 AND
t2.Col2 = 'AAA' AND
t2.t3 <> 0)
)
该查询执行时间很长。
但是,如果我将@Param1
替换为1
,则查询执行时间约为2秒。
任何有关如何解决问题的信息将不胜感激。
好了,解释似乎很简单。 对于当前条件,由于@Param1=0
为false(您之前将参数设置为1),因此它需要评估第二个条件,因为它有一个子查询,可能会花费很长时间。 如果将第一个过滤器更改为@Param1=1
,则表示它是正确的,并且无需评估第二个过滤器,从而使查询更快。
您似乎将优化器与OR语句混淆了。 如果删除它,您会发现它为SELECT语句生成了两个不同的执行计划-一个带有过滤器,另一个没有:
DECLARE @Param1 BIT
SET @Param1 = 1
if @Param1=0
begin
SELECT
t1.Col1,
t1.Col2
FROM
Table1 t1
end
else
begin
SELECT
t1.Col1,
t1.Col2
FROM
Table1 t1
WHERE
(t1.Col2 in
(SELECT t2.Col4
FROM
Table2 t2
WHERE
t2.Col1 = t1.Col1 AND
t2.Col2 = 'AAA' AND
t2.t3 <> 0)
)
end
这通常称为N + 1问题。
您在表1中进行选择,对于找到的每个记录,您将在表2中查找内容。
通过将@ Param1设置为在选择中将永远找不到的值,SQL引擎将跳过子查询。
为了避免这种行为,您可以使用JOIN语句将两个表连接在一起,然后使用where语句过滤结果。 join语句将比单个子查询慢一些,因为您要相互匹配2个表,但是由于只需要执行一次联接(相对于N次),您将获得严重的性能提升。
示例代码:
DECLARE @Param1 BIT
SET @Param1 = 1
SELECT t1.Col1,t1.Col2
FROM Table1 t1
INNER JOIN Table2 t2 on t1.Col1 = t2.Col1
WHERE @Param1=0
OR t2.Col2 = 'AAA'
AND t2.t3 <> 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.