在 SQL 中添加额外的 Where 子句会对性能造成很大影响

发布于 2024-10-13 02:33:05 字数 539 浏览 3 评论 0原文

我有一个运行多个视图和表的 SQL 查询。

查询运行良好,但当我在 WHERE 子句中添加另一个条件时,它开始对性能产生巨大影响。

查询的结构如下...

         SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND a.Column2 LIKE ISNULL(@parameter, a.Column2)

从上面的查询中,当我在 WHERE 子句中添加其他条件时,我的查询现在需要花费大量时间(超过 3 分钟)来执行并返回 1000 条记录。删除添加的条件子句和查询,不到 7 秒即可返回记录。

谢谢。 我应该检查什么来确定性能受到巨大影响的地方

I have an SQL Query that runs through multiple views and tables.

The query runs fine, but when I added another condition in the WHERE clause, it started to have tremendous hit on the performance.

The query is structured like...

         SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND a.Column2 LIKE ISNULL(@parameter, a.Column2)

From the query above, when I add the other condition in the WHERE clause, my query now takes a lot of time (more than 3 minutes) to execute and return 1000 records. Removing the added conditional clause and query returns the records in less than 7 secs.

Thanks.
What should I be checking to see where the performance hit is tremendous

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

安静 2024-10-20 02:33:05

查看查询的执行计划。我敢打赌,你的额外搜索参数会导致表扫描,从性能角度来看,这是一个非常昂贵的过程。

Look at your query's execution plan. I'll bet dollars to donuts that your additional search argument is causing a table scan, a very costly procedure, performance-wise.

九歌凝 2024-10-20 02:33:05

您的查询子句AND a.Column2 LIKE ISNULL(@parameter, a.Column2)涉及调用函数,因此SQL Server必须执行表扫描(即测试该函数)针对表中的每一行)来查看它是否满足查询。

即使您在 a.Column2 上有索引,Sql Server 也无法使用它。

[编辑]这是在大多数情况下加快速度的一种方法

-- Only this part executes when the @parameter has a value.
-- It returns nothing and executes fast when @parameter is NULL

SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND a.Column2 LIKE @parameter

UNION ALL

-- This part does not execute when the @paramter has a value
-- This will leave the 2nd query clause out and run faster when @parameter is not specified, avoiding a table scan

SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND @parameter IS NULL

Your query clause AND a.Column2 LIKE ISNULL(@parameter, a.Column2) involves calling a function, so SQL Server has to do a table scan (ie test that function against every row) in your table to see if it satisfies the query.

Even if you had an index on a.Column2, Sql Server would not be able to use it.

[EDIT] This is one way to speed it up in most cases

-- Only this part executes when the @parameter has a value.
-- It returns nothing and executes fast when @parameter is NULL

SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND a.Column2 LIKE @parameter

UNION ALL

-- This part does not execute when the @paramter has a value
-- This will leave the 2nd query clause out and run faster when @parameter is not specified, avoiding a table scan

SELECT a.*
           FROM vw_myView a
LEFT OUTER JOIN tbl1 b ON a.ID = b.ID
LEFT OUTER JOIN vw_OtherView c ON a.ID = c.ID
LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID
          WHERE a.Column1 = 'VALUE'
            AND @parameter IS NULL
清风不识月 2024-10-20 02:33:05

动态 SQL 可能是您最好的选择。如果参数为空,则创建一条语句;如果参数不为空,则创建另一条语句。这是使用大量可能的参数来加快搜索速度的常见方法。

由于你只有两个条件,我可能会尝试这样写:
IF @parameter IS NULL

BEGIN
    SELECT a.*            
    FROM vw_myView a 
    LEFT OUTER JOIN tbl1 b 
    ON a.ID = b.ID 
    LEFT OUTER JOIN vw_OtherView c 
    ON a.ID = c.ID 
    LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID           
    WHERE a.Column1 = 'VALUE'             
    AND a.Column2 LIKE a.Column2 
END
ELSE 
BEGIN
    SELECT a.*            
    FROM vw_myView a 
    LEFT OUTER JOIN tbl1 b 
    ON a.ID = b.ID 
    LEFT OUTER JOIN vw_OtherView c 
    ON a.ID = c.ID 
    LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID           
    WHERE a.Column1 = 'VALUE'             
    AND a.Column2 LIKE  @parameter
END

当然,您不应该在生产代码中使用 SELECT * 并在可能的情况下使用 = 而不是 LIKE。如果这些视图引用相同的表,则直接查询表可能是性能更好的选择。

Dynamic SQL is probably your best bet. Create one statement if the parameter is null and different one if it is not. This is the common way that searches are made faster with lots of possible parameters.

Since you only have the two conditions, I might try to write it like this:
IF @parameter IS NULL

BEGIN
    SELECT a.*            
    FROM vw_myView a 
    LEFT OUTER JOIN tbl1 b 
    ON a.ID = b.ID 
    LEFT OUTER JOIN vw_OtherView c 
    ON a.ID = c.ID 
    LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID           
    WHERE a.Column1 = 'VALUE'             
    AND a.Column2 LIKE a.Column2 
END
ELSE 
BEGIN
    SELECT a.*            
    FROM vw_myView a 
    LEFT OUTER JOIN tbl1 b 
    ON a.ID = b.ID 
    LEFT OUTER JOIN vw_OtherView c 
    ON a.ID = c.ID 
    LEFT OUTER JOIN tbl2 d ON c.OtherID = d.OtherID           
    WHERE a.Column1 = 'VALUE'             
    AND a.Column2 LIKE  @parameter
END

Of course you should not use SELECT * ever in production code and use = if possible instead of LIKE. And if those views reference the same tables, directly querying the tables might be abetter choice for performance.

九厘米的零° 2024-10-20 02:33:05

试试这个。

AND (a.Column2 = @parameter OR @parameter is NULL)

不明白为什么要使用like?

你想做这样的事情吗

AND (a.Column2 like @parameter+'%' OR @parameter is NULL)

try this.

AND (a.Column2 = @parameter OR @parameter is NULL)

Don't get why you are using like?

do you want to do something like this

AND (a.Column2 like @parameter+'%' OR @parameter is NULL)
卖梦商人 2024-10-20 02:33:05

为什么要这样做? AND a.Column2 LIKE ISNULL(NULL, a.Column2)
总是会检查a.Column2 LIKE a.Column2
您是否想仅检查a.Column2 IS NULL

您能否按照修改前的情况发布查询?

[编辑]
我不知道您的目标数据库,但如果它是 Sybase,我会警告您不要使用 @parameter + '%' 这将执行表扫描。您可以阅读更多内容 喜欢或不喜欢喜欢

Why do this? AND a.Column2 LIKE ISNULL(NULL, a.Column2)
That is always going to check a.Column2 LIKE a.Column2
Are you trying to just check a.Column2 IS NULL?

Can you pls post the query as it was before you modified?

[Edit]
I don't know your target database, but if it is Sybase I would caution you against using @parameter + '%' which will do a table scan. You can read more at To LIKE or not to LIKE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文