当前位置:  开发笔记 > 编程语言 > 正文

我应该索引SQL Server中的位字段吗?

如何解决《我应该索引SQLServer中的位字段吗?》经验,为你挑选了6个好方法。

我记得在某一点上读取索引具有低基数(少量不同值)的字段并不值得做.我承认我对索引如何理解为什么不够了解.

那么,如果我有一个包含1亿行的表,并且我选择位字段为1的记录呢?让我们说在任何时间点,只有少数记录位字段为1(而不是0).是否值得索引该位字段?为什么?

当然我可以测试它并检查执行计划,我会这样做,但我也很好奇它背后的理论.什么时候基数很重要,什么时候不重要?



1> Geoff Cox..:

考虑SQL中的索引是什么 - 而索引实际上是指向其他内存块(即指向行的指针)的一块内存.索引被分成页面,以便可以根据使用情况从内存中加载和卸载索引的某些部分.

当您要求一组行时,SQL使用索引比表扫描更快地查找行(查看每一行).

SQL具有聚簇索引和非聚簇索引.我对聚簇索引的理解是它们将类似的索引值分组到同一页面中.这样,当您要求所有与索引值匹配的行时,SQL可以从内存的聚簇页面返回这些行.这就是为什么尝试集群索引GUID列是一个坏主意 - 您不要尝试集群随机值.

索引整数列时,SQL的索引包含每个索引值的一组行.如果你的范围是1到10,那么你将有10个索引指针.根据有多少行,可以不同地分页.如果您的查询查找匹配"1"的索引,然后查找Name包含"Fred"的位置(假设Name列未编入索引),则SQL会非常快速地获取与"1"匹配的行集,然后通过表扫描查找其余行.

那么SQL真正在做的是尝试减少它必须迭代的工作集(行数).

索引位字段(或某个窄范围)时,只会将工作集减少与该值匹配的行数.如果你有少量的行匹配它会减少你的工作集很多.对于50/50分布的大量行,与保持索引最新相比,它可能会为您带来非常小的性能提升.

每个人都说要测试的原因是因为SQL包含一个非常聪明且复杂的优化器,如果它决定表扫描更快,或者可能使用排序,或者可能组织内存页面,它可能会忽略索引,但它很喜欢.


在我之前的评论中,我的意思是这句话:"当你索引一个位字段(或一些窄范围)时,你只将工作集缩减一半"如果分布的权重高于一个值则不成立.但我喜欢你的其余答案,所以如果你解决了,我会接受它.

2> Ben Thul..:

我只是通过另一个问题来看待这个问题.假设您的声明只有少数记录假定值为1(并且那些是您感兴趣的那些),那么过滤后的索引可能是一个不错的选择.就像是:

create index [IX_foobar] on dbo.Foobar (FooID) where yourBitColumn = 1

这将创建一个小得多的索引,优化器足够聪明,当它是查询中的谓词时使用.


有办法绕过这个,但你是对的; 优化器在编译时需要保证与筛选的索引谓词匹配的任何谓词的值都是静态/不变的,因为优化器的工作是创建一个适用于*any*参数集的通用计划.

3> C. Dragon 76..:

1亿个记录,只有少数记录的位字段设置为1?是的,我认为索引位字段肯定会加快查询bit = 1记录.您应该从索引获取对数搜索时间,然后只触摸bit = 1记录的几个页面.否则,您必须触摸1亿记录表的所有页面.

然后,我绝对不是数据库专家,可能会遗漏一些重要的东西.



4> 小智..:

如果您的分布是众所周知且不平衡的,例如99%的行是bit = 1而1%是bit = 0,那么当您使用bit = 1执行WHERE子句时,全表扫描将与索引扫描.如果你想快速查询bit = 0,我知道的最好方法是创建一个过滤索引,添加一个子句WHERE bit = 0.这样,该索引只存储1%的行.然后执行WHERE位= 0将简单地让查询优化器选择该索引,并且其中的所有行都将为bit = 0.还有一个好处是比较位上的完整索引需要非常少量的磁盘空间.


如果99%的行是bit = 1,则优化器应忽略索引并执行表扫描.使用索引实际上是_worse_而不是表扫描,至少在旋转驱动器上,更多的I/O和从磁盘的非连续读取.过滤后的索引(Postgres等效:部分索引)是要走的路.我想因为问题已经过了几年,这个答案没有得到应得的票数.

5> BradC..:

虽然我不认为我会单独索引JUST一个列,但将列列作为复合索引的一部分是很常见的.

一个简单的例子是当您的应用程序几乎总是在寻找活跃客户时,ACTIVE,LASTNAME而不是lastname上的索引.


在你给出的例子中,我更倾向于将LastName放在第一位.它取决于特定的查询工作负载,但通常首先具有更多选择性列,意味着更有可能使用索引.

6> Jeff..:

如果您还没有阅读,Jason Massie最近写了一篇文章,讨论了这个话题.

http://statisticsio.com/Home/tabid/36/articleType/ArticleView/articleId/302/Never-Index-a-BIT.aspx

编辑:新文章位置 - http://sqlserverpedia.com/blog/sql-server-bloggers/never-index-a-bit

以前"新"文章位置的Wayback机器:http://web.archive.org/web/20120201122503/http : //sqlserverpedia.com/blog/sql-server-bloggers/never-index-a-bit/

新的SQL Server Pedia位置是Toadworld,其中有一篇来自Kenneth Fisher的新文章讨论了这个主题:

http://www.toadworld.com/platforms/sql-server/b/weblog/archive/2014/02/17/dba-myths-an-index-on-a-bit-column-will-never-be- used.aspx

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有