在条款中包含许多值 - SQL

时间:2013-07-11 18:22:54

标签: sql sql-server performance tsql case

我需要你的建议。

我的T-SQL查询中有CASE语句,如下所示:

CASE 
    WHEN PLAN_GIVEN IN ( this list contains 1700 values to compare ) THEN 'P1'
    WHEN PLAN_GIVEN IN ( this list contains 1800 values to compare ) THEN 'P2'  
    ELSE NULL
END AS PLAN_NAME

我无法列出所有1700个值IN ( ) THEN 'P1',因为它对所有这些值都不会很好。

我尝试将1700个值和1800个值保存到lookup_table

lookup_table  

columnA = all 1700 values                 
columnB = all 1800 values

并使用此查询:

CASE 
    WHEN PLAN_GIVEN IN (SELECT columnA from lookup_table) THEN 'P1'
    WHEN PLAN_GIVEN IN (SELECT columnB from lookup_table) THEN 'P2'  
    ELSE NULL
END AS PLAN_NAME

上面的代码正在运行,但执行差不多10分钟才能完成执行。

有没有其他方法可以实现这一目标?

4 个答案:

答案 0 :(得分:3)

请尝试使用PLAN_GIVEN IN

,而不是使用EXISTS
CASE 
    WHEN EXISTS (SELECT NULL from lookup_table WHERE PLAN_GIVEN = columnA) 
         THEN 'P1'
    WHEN EXISTS (SELECT NULL from lookup_table WHERE PLAN_GIVEN = columnB) 
         THEN 'P2'  
ELSE NULL
END AS PLAN_NAME

或者,尝试加入查找表并与CASE表达式中的查找值进行比较:

SELECT ...
       CASE PLAN_GIVEN
           WHEN lookup_table.columnA THEN 'P1'
           WHEN lookup_table.columnB THEN 'P2'  
           ELSE NULL
       END AS PLAN_NAME
       ...
FROM ...
LEFT JOIN lookup_table 
  ON PLAN_GIVEN IN (lookup_table.columnA, lookup_table.columnB)

答案 1 :(得分:3)

我将查找表更改为:

Value  Name
-----  ----
123    P1
456    P1
...    ...
789    P2
...    ...

Value上使用聚集索引。

之后,你可以简单地在LookupTable.Value = otherTable.PLAN_GIVEN上外连接查找表,只需在SELECT子句中拉LookupTable.Name,即这样:

SELECT
  ...
  lookup.Name AS PLAN_NAME,
  ...
FROM
  ...
  LEFT OUTER JOIN LookupTable lookup ON lookup.Value = otherTable.PLAN_GIVEN
WHERE...
...

请注意,我假设查找值是唯一的,在我看来你在CASE表达式中如何处理它们时,这似乎很自然。

答案 2 :(得分:1)

首先使用@MarkBannister提供的解决方案之一。第二个在lookup_table的每一列上放置索引。

 CREATE INDEX IX_lookup_table_A ON lookup_table(columnA)
 CREATE INDEX IX_lookup_table_B ON lookup_table(columnB)

即使lookup_table是临时表,仍然值得花时间添加索引。如果它是静态表,那么它的值得花时间。

答案 3 :(得分:0)

值得一试

select 'P1' 
from table 
where PLAN_GIVEN IN ( this list contains 1700 values to compare ) 
union 
select 'P2' 
from table 
where PLAN_GIVEN IN ( this list contains 1800 values to compare ) 

如果PLAN_GIVEN在索引中,那么这可以使用索引 我不认为CASE可以使用索引。

也许是TVP而不是