English 中文(简体)
数据库索引:仅选择!
原标题:
  • 时间:2008-12-08 23:56:12
  •  标签:

你好

I have about 4GB of data, separated in about 10 different tables. Each table has a lot of columns, and each column can be a search criteria in a query. I m not a DBA at all, and I don t know much about indexes, but I want to speed up the search as much as possible. The important point is, there won t be any update, insert or delete at any moment (the tables are populated once every 4 months). Is it appropriate to create an index on each and every column? Remember: no insert, update or delete, only selects! Also, if I can make all of these columns integer instead of varchar, would i make a difference in speed?

非常感谢!

问题回答

答案:不。将每列单独建立索引不是一个好的设计。在许多情况下,索引需要包括多个列,并且不同类型的索引有不同的需求。

在其他答案中提到的调音向导是一个不错的初步选择(特别是对于学习者来说)。

不要试图猜测,也不要希望自己能理解复杂的分析 - 获得针对您情况的具体建议。我们似乎有几个讨论贴,针对特定情况和查询优化,十分活跃。

你看过运行索引调整向导吗?它会根据工作负载为你提供索引建议。

绝对不是。

你必须明白索引的工作原理。比如说,如果你有一个有 1000 条记录的表,但它是一个二进制位,只有两个值,如果你只在那个列上建立索引,它会毫无用处,因为它不够具有选择性。当你在一个列上建立索引时,要非常注意将来对表执行的选择类型。当你在一列上创建索引时,这个索引是否具有足够的选择性以便优化程序能够有效地使用它?

到这一点上,你很可能会发现一些精心挑选的复合索引会比对每一列进行单独索引的解决方案表现要好得多。黄金法则:查询数据库的方式将决定你应该如何创建你的索引。

两个缺失的信息:每列有多少个不同的值,以及您使用哪种DBMS。如果您使用的是Oracle,并且每列少于几千个不同的值,则可以创建位图索引。对于精确匹配,这些索引非常节省空间和执行效率。

否则,这是个权衡:每个索引增加的大致空间与包含相同数据的单列名字相同,因此您基本上会使空间需求翻倍(可能会增加2.5倍)。因此,可能是10G,这并不是很多数据。

然后就有一个问题,那就是您的数据库管理系统是否可以有效地合并多个基于索引的选择条件。很可能不行,除非您针对每个您选择的列进行自连接。

最佳答案:尝试在较小的数据集上进行(这样就不必花费所有时间来构建索引),看看效果如何。

如果你从一个表中选择的列集合大于那些被选中索引覆盖的列,那么你将不可避免地在查询计划中遇到书签查找。这时查询处理器需要使用关联的非聚集索引的叶行中的引用 ID 从聚集索引中检索非覆盖列。

在我的经验中,由于需要进行额外的读取并且每个聚集索引中的行必须单独解决,因此书签查找可能会严重影响查询性能。这就是为什么我尽可能尝试使用非聚集索引来涵盖,这在较小的表中更容易实现,因为所需的查询计划是众所周知的,但如果您有大型表并且有许多带有任意查询的列,则可能无法实现。

这意味着只有在NC索引覆盖或选择小型数据集,以减轻书签查找的成本时,您才能获得最大回报 - 实际上,如果成本与聚集索引扫描相比禁止,则查询优化器甚至可能不会查看您的索引,因为所有列已经可用。

因此,除非您知道索引将优化特定查询的结果,否则创建索引是没有意义的。索引的价值因此与它可以优化给定表的查询的百分比成比例,而这只能通过分析正在执行的查询来确定,这正是Index Tuning向导为您完成的工作。

所以总结一下:

不要索引每一列,这是典型的过早优化。你不能提前为所有可能的查询计划为大表优化索引。

在通过索引调整向导捕获并运行基本工作负载之前,请不要索引任何列。此工作负载需要代表您的应用程序的使用模式,以便向导可以确定哪些索引实际上会有助于查询的性能。 Translation: 直到您捕获并运行了基本工作负载通过索引调整向导之前,请勿索引任何列。此工作负载需要代表您的应用程序的使用模式,这样向导才能确定哪些索引实际上有助于查询的性能。





相关问题
热门标签