我在SQL Server 2008中有一个包含数千万条记录的表。 第一列(ID)是主键。其他列不可索引。
需要列出ID为30的倍数的所有记录。所以我写道:
SELECT ID,... FROM table1 WHERE (ID between value1 AND value2) AND (ID % 30 = 0)
即使结果仅包含100条记录,此查询太也很慢。 因此,除非找到更快的解决方案,否则我的数据库是没用的。
我的数据库的特殊功能是:
我从未在此表中更新过值。只有INSERT和SELECT。
每个新记录(INSERT)的ID大于表中以前的所有现有ID。 (ID按升序排列)。
答案 0 :(得分:2)
您所拥有的只是索引。因此,您必须根据B树,键顺序和范围来表达问题。要减少执行时间,必须减少查询扫描的行范围。有几种可能的方法:
ID
上为谓词ID % 30 = 0
创建筛选索引,并包含投影列。这将仅适用于<{1}} WHERE ID % 30 = 0
创建一个持久计算列,并将其添加为聚簇索引中最左侧的键(由于选择性较低)。这适用于ID % 30
,但也适用于WHERE ID % 30 =0
或WHERE ID % 30 = 1
。但不适用于WHERE ID % 30 = 29
。如你所见,选项并不是那么好。这个要求是非常不寻常的,我实际上怀疑它是一个严肃的业务需求,它似乎更像是一个选择的实现的工件,用于更通用的要求。如果您说出您的业务需求,我们可能会提供更好的解决方案。