我有一个大表(数千万到数亿条记录),出于性能原因,我们已将其拆分为活动表和存档表,使用直接字段映射,并且每晚运行存档进程。
在我们的代码中的几个地方,我们需要运行结合活动表和存档表的查询,几乎总是由一个或多个字段过滤(我们显然在两个表中都放置了索引)。为方便起见,有这样的视图是有意义的:
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 查找?)但存档表正在执行表扫描!
对该问题的评论表明,问题在于 OP 用于开发查询的测试数据库具有与生产数据库完全不同的数据特征。它的行数要少得多,并且用于过滤的字段的选择性不够。
当列中不同值的数量太少时,索引可能没有足够的选择性。在这种情况下,顺序表扫描比索引查找/行查找操作便宜。通常,表扫描会大量使用顺序 I/O,这比随机访问读取要快得多。
通常,如果查询将返回超过百分之几的行,那么仅进行表扫描会比索引查找/行查找或大量使用随机 I/O 的类似操作便宜。
只是补充一下,我发现了什么。如果你这样做:
然后您可以过滤 [Active] 字段,并确保未加载其他部分。