为SQL Server定义索引(群集和非群集)时,您会考虑哪些事项? DB新手应该注意哪些反模式?请解释“为什么”或尽可能提供参考。
答案 0 :(得分:13)
索引基本上是“备忘单”。它允许DBMS在磁盘上查找特定值(或值范围),而无需扫描整个表。一般来说,你通过索引在INSERT / UPDATE / DELETE上付出一点点代价,但很少这么说它本身就是一个瓶颈。一个好的DBMS只会在它们帮助查询性能时使用索引,因此这里没有很多非常消极的反模式;如果你有额外的索引,它通常不会对你造成太大伤害(除非你在谈论非常高度的事务表)。也就是说,全面仔细索引将帮助您确保真正重要的索引存在,并且发现这一点的最佳方式是分析您的应用程序。
了解何时以及何时不使用索引的关键是要掌握他们在幕后的实际行动。简而言之,当索引的选择性很高时(即,与关系的大小相比,不同可能值的数量较高),您需要它们。因此,例如,如果你有一个包含10,000行的表,并且你在该表上有一个名为“color”的列,它是“红色”或“蓝色”,那么拥有索引并没有多大帮助,因为DBMS可能必须将大部分页面加载到内存中(假设随机分布)。相反,表的主键id(几乎总是自动添加)的索引将使该表中的查找快速 - 按log(n)的顺序 - 因为树中的非常少量的节点必须检查以找到记录所在的磁盘上的页面。
大多数现代数据库系统中的索引都是使用B +树实现的,B +树是B-Trees的一种非常酷的变体,它针对慢速二级存储(磁盘而不是内存)进行了优化。您可以从Database Systems: The Complete Book获得对其使用和功能的良好介绍。
答案 1 :(得分:4)
如果没有填充代表性数据的数据库,请不要测试索引或优化查询。
数据库通常会忽略布尔字段上的任何索引。它将忽略它作为复合索引的一部分。 (但是,请参阅SQL Server 2008中的“筛选索引”。)
对于将提供所有值的复合索引,按基数(或者arity,或者数据中有多少个不同的值)以相反的顺序枚举它们。
不要假设任何事情。测试一切。
您只有一个聚集索引。不要把它浪费在一个独特的索引上,除非你确定你真的需要几乎总是拉出该列上排序的行。您希望将它用于经常提取多个相邻行的情况。
“覆盖”索引本身包含解析选择所需的所有字段。请记住,在大多数关键情况下,“几乎”覆盖的索引都不够好。
您在在线博客中阅读的关于设计索引的大部分内容都是错误的,或者是高度合格的,在您的情况下不适用,或者在收益和成本方面进行了严格校准。
答案 2 :(得分:2)
大胆的 - 过去我曾经犯过一个索引反模式。将相同索引的索引或变体放在表中的列上,而不必查看解释计划或真正了解优化程序的工作方式。
答案 3 :(得分:2)
以下是我见过或曾经犯过的一些索引反模式:
一揽子报道 - 在没有增长或没有(非常)低行数的表上放置索引。这会适得其反,因为索引查找可能比表扫描花费更长时间。
工业强度指数 - 在主键列上放置索引。我被要求这样做以“加速”查询。
答案 4 :(得分:1)
考虑阅读Relational Database Index Design and the Optimizers。它会给你很多想法以及它们为什么好的原因。
答案 5 :(得分:1)
我看到一种人们正在使用数据库引擎优化顾问的模式,并认为它在某种程度上足够聪明,可以建议最佳的索引和统计数据。这是你应该避免的模式。
在决定如何进行优化之前,请先查看您的查询计划输出。他们可以告诉您有关如何最好地处理查询的大量有用信息。通常人们会在所有类型的字段上抛出索引,因为他们认为这是正确的做法,忽略了在某些情况下他们可能实现的任何收益可能会被索引本身的影响(表格上的大量索引)整体否定可以减慢插入和更新速度。)
下次当你在书店时,拿起一本关于由Itzik Ben-Gan(MS Press)进行的T-SQL查询的书(他们会有它)。阅读前3章,它将介绍查询过程如何在SQL Server中运行 - 就您使用这种特定技术而言,它们可能被证明是您将阅读过的最重要的3章。
答案 6 :(得分:1)
有一件事我发现,当索引编制索引外键时,人们忘了这么做。主键索引是自动构建的(我说她是SQL Server,其他数据库可能有所不同)但外键不是。但是很多人都认为他们是(大概是假设触发器的人一次只能在一条记录上行动)。因为它们几乎总是涉及连接(为什么还有一个?),它们需要在大多数时间被索引(Exception将是一个非常小的表)。
我会将我最喜欢的索引反模式定义为: 为什么我的查询如此慢 - 当非数据库人设计大型数据库并且甚至不知道在其上放置任何索引时发生的情况。在留言板上找到典型的症状,该人询问为什么需要40分钟对其5000万记录表进行简单查询。可能这种反模式会出现很多其他数据库设计反模式,因为甚至不熟悉索引的人不太可能设计出有效或有效的数据库结构。
答案 7 :(得分:1)
在GUID列上放置聚簇索引通常不是一个好主意。 聚簇索引定义数据存储方式的物理顺序。因此,最好将聚簇索引放在增量或减量的列上,并且该列是唯一的 (如果聚簇索引不是唯一的,SQL Server将在内部将PK添加到聚簇索引)。 Guid是一个随机值(除非你确保使用顺序guid),所以这意味着每次在作为聚簇索引一部分的列中插入或更新guid时,Sql Server都必须移动记录。数据页。
另外,尝试在您经常用于执行“范围”搜索的列上放置聚簇索引。