当条件要求在列表中搜索大量字段时,加速查询

时间:2015-09-01 13:42:55

标签: sql-server

我正在处理一些大型健康数据表(3B +行),并负责根据医疗代码列表标记和选择行。

考虑表EVENT

( id bigint
, edate date
, d1 char(5), d2 char(5), d3 char(5), d4 char(5), d5 char(5), d6 char(5), d7 char(5), d8 char(5), d9 char(5), d10 char(5)
, p1 char(5), p2 char(5), p3 char(5), p4 char(5), p5 char(5), p6 char(5), p7 char(5), p8 char(5), p9 char(5), p10 char(5)
, and many other fields
)

必须被查询并且标记为

select * from 
(
 select ...
 , case when
    p1 in (x1, ... ,xN1) or ... or p10 in (x1, ... ,xN1) then 'Y' else 'N' end as X_FLAG
 , case when
    p1 in (y1, ... yN2) or ... or p10 in (y1, ... ,yN2) then 'Y' else 'N' end as Y_FLAG
 , case when
    d1 in (z1, ... ,zN3) or ... or p10 in (z1, ... ,zN3) then 'Y' else 'N' end as Z_FLAG
 , case when
    d1 in (q1, ... ,qN4) or ... or d10 in (q1, ... ,qN4) then 'Y' else 'N' end as Q_FLAG
...
 from EVENT
 where
...
) tagged
into FURTHER_STUDY
where X_FLAG='Y' or Y_FLAG='Y' or Z_FLAG='Y' or Q_FLAG='Y'

随着搜索字段数和分配的标记数,查询持续时间会越来越长。

是否有更好的方法来制定速度查询? 例如,执行OR的快捷方式,或者每个长OR链是否更好作为更大的CASE语句?

可以/应该使用逐行扫描的程序吗?

2 个答案:

答案 0 :(得分:0)

如果在运行时对30亿行进行任何类型的数据操作,特别是对于这么多case语句,查询将花费时间来处理数据。

毕竟3个billon行不是一个小数字。另外,我希望你在某种数据仓库中有这些3B行,而不是在OLTP数据库中。

我认为计算列可能是一种可能的解决方案。为Flag_X,Y Z G等添加这四列,并计算它们是否获得任何性能增益。

计算列的一个例子,类似于你的要求,就像......

表架构

DECLARE @t TABLE 
 ( ID INT 
 , ID2 INT 
 , Flag_X AS (CASE WHEN ID IN (1,2) OR ID2 IN (1,2) THEN 1 ELSE 0 END) PERSISTED
 , Flag_Y AS (CASE WHEN ID IN (2,3) OR ID2 IN (2,3) THEN 1 ELSE 0 END) PERSISTED)

INSERT INTO @t(ID , ID2) VALUES 
(1 , 1),
(3 , 1),
(3 , 3) 

测试

SELECT * FROM @t 

╔════╦═════╦════════╦════════╗
║ ID ║ ID2 ║ Flag_X ║ Flag_Y ║
╠════╬═════╬════════╬════════╣
║  1 ║   1 ║      1 ║      0 ║
║  3 ║   1 ║      1 ║      1 ║
║  3 ║   3 ║      0 ║      1 ║
╚════╩═════╩════════╩════════╝

答案 1 :(得分:0)

这是我可能会使用多个步骤的罕见案例之一,而不是试图将其纳入单一陈述。

但是如果我绝对不得不把它放到一个语句中,我会把这些标志放到他们自己的表中,然后我会加入该表而不是使用IN ()子句。这将简化查询(无需列出可能很长的选择器列表)并提高性能(新标志表可以包含有助于Sql Server生成结果的索引和统计信息)。

我仍然做的是写一个过程或光标来逐行扫描。如果需要,Sql Server已经可以做到这一点,并且正是这样做可能会导致为什么这会变慢。当我说“几个步骤”时,我的意思是更像是所有XFlags的一步,所有YFlags的一步等等。