如何优化此查询(在AND验证中)?

时间:2011-11-29 19:25:20

标签: sql sql-server tsql query-optimization

我遇到此查询的问题:

SELECT col1, col2,col3,...,coln FROM MyTable
WHERE col1 = @value1
AND
(
ISNULL(col2,'c') = ISNULL(@value2,ISNULL(col2,'c'))
OR
ISNULL(col3,'c') = ISNULL(@value2,ISNULL(col3,'c'))
)
 AND coln = 'valueN'

我必须停止执行,它太慢了。但是编辑:

SELECT col1, col2,col3,...,coln FROM MyTable
WHERE col1 = @value1
AND
(
ISNULL(col2,'c') = ISNULL(@value2,ISNULL(col2,'c'))
)
AND coln = 'valueN'

此查询更快。有人能帮我吗?如何替换or语句或替换查询但验证col1和col2?。 感谢。

更新

非常感谢你们。我的查询真的不使用'=',而是使用'赞',抱歉。但是,我使用您的建议来构建我的查询,它工作正常:

SELECT col1, col2,col3,...,coln FROM MyTable
WHERE col1 like '%' + @value1 + '%'
AND
(
 (@value2 IS NULL)
 OR
  (col2 IS NOT NULL AND col2 LIKE '%' + @value2 + '%')
 OR
 (col3 IS NOT NULL AND col3 LIKE '%' + @value2 + '%')
)
 AND coln = 'valueN'

我将这个查询用于一个页面,其中我有很多字段来过滤搜索,我需要将col2文本框也应用于数据库中的col3,我想要的是,在数据库中只有一个文本框用于name1和name2。

抱歉,我的错误问题,谢谢你的建议。

2 个答案:

答案 0 :(得分:3)

ISNULL(col2,'c') = ISNULL('value2',ISNULL(col2,'c'))

相同
col2 = 'value2' or (col2 is null and 'value2' is null)

替换事件,您很可能会有更好的表现。

<强>更新

这个解决方案与@onedaywhen提出的解决方案之间存在一个根本区别:当'value2'中提供的值(我想这只是一个组装成SQL字符串的参数)是{{1 OP只想恢复col2为NULL的记录。仔细研究OP的逻辑,你会看到那里。 OP的逻辑始终过滤器:当参数为NULL时,OP希望记录NULL

当参数为col2 is NULL时, @ onedaywhen的解决方案会带来每条记录。虽然这是一个非常常见的查询,但并非OP正在寻找

答案 1 :(得分:1)

ISNULL(col2,'c') = ISNULL(@value2,ISNULL(col2,'c'))

相同
( ( col2 = @value2 ) OR ( @value2 IS NULL ) ) 

我不确定这是否会提高性能:我已经读过,至少对于SQL Server 2005及更早版本,to get an efficient, scalable and performant solution either use IF ELSE control of flow blocks (one per parameter combination) or use dynamic SQL


更新:......这是证据:


查询1:当参数是非空值时:

DECLARE @value2 VARCHAR(10);
SET @value2 = 'Apples';
WITH T 
     AS 
     (
      SELECT * 
        FROM (
              VALUES (1, 'When col2 is null', NULL), 
                     (2, 'When col2 is the same value as @value2', 'Apples'), 
                     (3, 'When col2 is not the same value as @value2', 'Oranges')
             ) AS T (ID, narrative, col2)
     )
SELECT *, 
       CASE WHEN ISNULL(col2,'c') = ISNULL(@value2,ISNULL(col2,'c')) THEN 'T' END AS OP, 
       CASE WHEN ( ( col2 = @value2 ) OR ( @value2 IS NULL ) ) THEN 'T' END AS OneDayWhen, 
       CASE WHEN col2 = @value2 or (col2 is null and @value2 is null) THEN 'T' END AS Adrian
  FROM T;

输出1:

ID          narrative                                  col2    OP   OneDayWhen Adrian
----------- ------------------------------------------ ------- ---- ---------- ------
1           When col2 is null                          NULL    NULL NULL       NULL
2           When col2 is the same value as @value2     Apples  T    T          T
3           When col2 is not the same value as @value2 Oranges NULL NULL       NULL

注意所有行都同意:)


查询2:当参数为null时:

DECLARE @value2 VARCHAR(10);
SET @value2 = NULL;
WITH T 
     AS 
     (
      SELECT * 
        FROM (
              VALUES (1, 'When col2 is null', NULL), 
                     (2, 'When col2 is the same value as @value2', 'Apples'), 
                     (3, 'When col2 is not the same value as @value2', 'Oranges')
             ) AS T (ID, narrative, col2)
     )
SELECT *, 
       CASE WHEN ISNULL(col2,'c') = ISNULL(@value2,ISNULL(col2,'c')) THEN 'T' END AS OP, 
       CASE WHEN ( ( col2 = @value2 ) OR ( @value2 IS NULL ) ) THEN 'T' END AS OneDayWhen, 
       CASE WHEN col2 = @value2 or (col2 is null and @value2 is null) THEN 'T' END AS Adrian
  FROM T;

输出2:

ID          narrative                                  col2    OP   OneDayWhen Adrian
----------- ------------------------------------------ ------- ---- ---------- ------
1           When col2 is null                          NULL    T    T          T
2           When col2 is the same value as @value2     Apples  T    T          NULL
3           When col2 is not the same value as @value2 Oranges T    T          NULL

注意OP和OneDay当所有行匹配时,Adrian仅匹配行ID = 1。