【发布时间】:2013-11-08 17:52:44
【问题描述】:
运行于: SQL Server 2008 R2 标准。虽然我认为这是所有数据库的问题,而不仅仅是 SQL Server。
背景:我一直听说/读过/被告知,索引的前沿应该是高度选择性的。当您有查询寻求特定值或一小组值(产品 ID 或类似的东西)时,这是有意义的。
一般性问题:非高选择性索引是否有用?
例如:我有一个包含 3.5 亿行的表。该表包含一堆价格。该表包含以下列:
-
priceId-- 表上的聚集索引 -
warehouseId-- fk 到 10 个仓库之一,平均分布在 150m 行中 -
algorithmId-- fk 到我计算价格的 23 种算法之一,平均分布在 1.5 亿行中 -
priceDate-- 我们上次计算价格的日期 productId
然后我运行这个查询:
select productId
from price
where warehouseId = 1
and algorithmId = 1
order by priceDate
具体问题:我不会从这样的索引中受益吗?
create nonclustered index ix_p
on price (warehouseId, algorithmId, priceDate) includes (productId)
看来我会受益 b/c 我已经创建了一个覆盖索引,过滤列组织得很好,这样 SQL Server 可以一次切出大块并按priceDate 排序。那有意义吗?它有效吗?
注意:我会试试这个,然后告诉你我发现了什么。
【问题讨论】:
-
索引策略几乎总是取决于您正在运行的查询。典型的观点是,如果您从表中选择超过 10% 的数据,则应该使用全扫描或分区而不是索引来访问该数据,因为索引需要两次磁盘读取 - 一次读取索引,另一个读取表上的数据...
-
谢谢。我已经稍微编辑了我的问题 b/c 我的意思是要明确这是一个覆盖非聚集索引,所以不需要回到表中。所有字段都可用作键列或包含列。
-
我考虑过分区,但我运行的是 2008 标准,我需要升级到企业才能获得分区功能。
-
您不必分区以将数据存储在多个驱动器上,也不必单独存储索引。如果索引当前存储在主索引上,您可能需要为索引创建一个文件组。
-
我的索引在一个单独的文件组中。该文件组有一个专用驱动器,与主驱动器或日志记录分开。我现在没有另一个驱动器可以跨越。这不是我要问的问题,真的。
标签: sql sql-server database indexing