Dan*_*l B 7 sql sql-server indexing sql-server-2008
我们目前有一个场景,其中一个表实际上有几个(10到15)布尔标志(不是可空bit字段).不幸的是,在逻辑层面上实际上不太可能简化这一点,因为布尔值的任何组合都是允许的.
有问题的表是一个事务表,最终可能有数千万行,插入和选择性能都非常关键.虽然我们目前还不太确定数据的分布,但是所有标志的组合应该提供相对良好的基数,即使其成为SQL Server使用的"有价值"索引.
典型的选择查询场景可能是仅基于3或4个标志来选择记录,例如WHERE FLAG3=1 AND FLAG7=0 AND FLAG9=1.为这些选择查询使用的所有标志组合创建单独的索引是不切实际的,因为它们中有很多.
鉴于这种情况,有效索引这些领域的建议方法是什么?该表是新的,因此现在还没有现有的数据需要担心,我们在表的实际实现中有相当大的灵活性.
目前我们正在考虑两个主要选项:
int总是使用的1或2个其他字段).我担心的是,鉴于仅包含一些字段的典型用法,此方法将跳过索引并采用表扫描.让我们称之为选项A(阅读了一些回复后,似乎这种方法效果不好,因为索引中字段的顺序会有所不同,因此无法在所有字段上有效地索引).目前,我们明显倾向于选择B.为了完整起见,这将在SQL Server 2008上运行.
任何建议将不胜感激.
编辑:拼写,清晰度,查询示例,选项B的其他信息.
单个BIT列通常不具有足够的选择性,甚至不能考虑在索引中使用.因此,单个BIT列上的索引确实没有意义 - 平均而言,您总是必须搜索表中大约一半的条目(50%选择性),因此SQL Server查询优化器将改为使用表扫描.
如果您在所有15 bit列上创建单个索引,那么您没有这个问题 - 因为您有15个是/否选项,您的索引将变得非常有选择性.
麻烦的是:位列的顺序很重要.只有在SQL语句使用最左侧BIT列中至少1-n的情况下才会考虑您的索引.
所以,如果您的索引已开启
Col1,Col2,Col3,....,Col14,Col15
Run Code Online (Sandbox Code Playgroud)
然后它可能用于使用的查询
Col1Col1 和 Col2Col1并Col2与Col3
....等等.但它不能用于指定Col6,Col9和的查询Col14.
因此,我并不认为您的BIT列集合上的索引真的很有意义.
这15 BIT列是您用于查询的唯一列吗?如果没有,我会尝试将您最常用的BIT列与其他列组合在一起,例如索引Name和/ Col7或某些东西(然后您的BIT列可以为另一个索引添加一些额外的选择性)
虽然可能有一些方法可以解决现有表模式的索引问题,但我会将其简化为规范化问题:
例如,我强烈建议创建一系列新表:
CREATE TABLE Flags (id int IDENTITY(1,1), Name varchar(256))(如果您想手动控制 id,则不必将 id 设置为身份种子列 - 例如 2,4,8,16,32,64,128 作为二进制标志。)CREATE TABLE DataFlags_Link (id int IDENTITY(1,1), MyFlagId int, DataId int)然后,您可以在表上创建索引DataFlags_Link并编写如下查询:
SELECT Data.*
FROM Data
INNER JOIN DataFlags_Link ON Data.id = DataFlags_Link.DataId
WHERE DataFlags_Link.MyFlagId IN (4,7,2,8)
Run Code Online (Sandbox Code Playgroud)
至于性能,这就是良好的 DBA 维护的用武之地。您需要适当地设置表上的 INDEX 填充因子和填充,并定期运行索引碎片整理或按计划重建索引。
性能和维护与数据库密切相关。两者缺一不可。
| 归档时间: |
|
| 查看次数: |
1793 次 |
| 最近记录: |