如何使联合视图更有效地执行?


8

我有一个大表(上千万个记录),出于性能原因,我们将其拆分为活动表和存档表,使用直接字段映射,并每晚运行一个存档过程。

在代码的几个地方,我们需要运行结合了活动表和归档表的查询,这些查询几乎总是被一个或多个字段过滤(我们显然已经在两个表中都添加了索引)。为了方便起见,有如下视图是有意义的:

create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive

但是如果我运行类似的查询

select * from vMyTable_Combined where IndexedField = @val

在使用过滤之前,它将对Active和Store中的所有内容进行合并@val,这会降低性能。

是否有任何巧妙的方法可以使并集的两个子查询@val在创建并集之前查看每个过滤器?

或者,也许您会建议采用其他方法来实现我的目标,即一种简单有效的方法来获取由索引字段过滤的联合记录集?

编辑:这是执行计划(您将在这里看到实际的表名):

执行计划

奇怪的是,活动表实际上使用了正确的索引(加上RID查找?),但是归档表正在执行表扫描!


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特9

Answers:


8

关于该问题的评论表明,问题在于OP用来开发查询的测试数据库具有与生产数据库完全不同的数据特​​征。它的行数少得多,用于筛选的字段不够选择性。

当列中的不同值的数量太小时,索引可能没有足够的选择性。在这种情况下,顺序表扫描比索引查找/行查找操作便宜。通常,表扫描大量使用顺序I / O,这比随机访问读取要快得多。

通常,如果查询返回的行数不止百分之几,那么仅进行表扫描要比索引查找/行查找或大量使用随机I / O的类似操作便宜。


1

补充一下,我发现了什么。如果您这样做:

create view vMyTable_Combined as
select *, 1 AS [Active] from MyTable_Active
union all
select *, 0 AS [Active] from MyTable_Archive

然后,您可以在[活动]字段中进行过滤,并确保未加载其他部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.