代码之家  ›  专栏  ›  技术社区  ›  Richard

是否有创建正确数据库索引的策略?

  •  2
  • Richard  · 技术社区  · 16 年前

    有人问了这个问题:“ INT, BIGINT or UUID/GUID in Oracle, DB2, Derby and HSQLDB? “我开始思考我设计的所有数据库模式,以及我读过的书,没有一个参考给出任何 真实的 清楚的 关于创建索引的建议。

    例如,如果您有类似

    date() ++ foo() ++ bar()
    

    虽然此索引很适合搜索和排序日期范围数据(读取;读取性能)…写作很糟糕。(插入总是发生在平衡树的右侧,强制重新平衡这是一个昂贵的操作)

    显然…a)了解您的数据。b)了解您的用例。c)了解数据库引擎。

    但是,定义高性能数据库的合理模式的一般规则是什么?

    2 回复  |  直到 16 年前
        1
  •  4
  •   Walter Mitty    16 年前

    好的,这里有一些关于索引生成的真正明确的建议:这取决于。

    这很清楚,但一点也不具体。如果你想要更具体的东西,你就必须了解它依赖于什么。

    它取决于您的DBMS,甚至可能取决于您的DBMS的版本。下面是一些你应该学习的流行语,至少表面上是这样。“表面上”我的意思是了解它对你有什么作用,以及它如何伤害你,但不一定是它是如何工作的。如果你能得到一个特定于你的数据库管理系统的文档,那就使用它。

    避免全表扫描。

    仅检索索引。

    范围检索。(和复合或复合指数)

    合并联接(稍后讨论)。

    哈希索引。

    并发控制(稍后讨论)。

    主键和索引(稍后讨论)。

    索引更新的成本。

    延迟了索引更新。

    基于成本的优化。如果你的DBMS没有CBO,那就换一个DBMS。

    提示。(如何使用它们,以及如何在没有它们的情况下生活。)

    数据库管理和CBO。有些DBMS需要定期进行DBA操作,以防止优化器使用过时的策略。

    它取决于容量:对于非常小的表,索引设计相对来说比较简单。我所说的“相对琐碎”,是指它相当容易,但也相当不重要。犯错的代价很低。如果您正在构建查找表,那么您肯定需要代码列上的唯一索引。如果将代码列声明为主键,您将得到这样一个表(使用大多数DBMS)。如果不创建任何其他索引,则成本可能是一个小表的表扫描,这种扫描是在一些可以容忍延迟的异常情况下进行的。

    任何模式中的大表往往是通过常规事务处理添加到其中的表。这增加了拥有一些索引的好处,包括速度和事务并发性。它还增加了拥有索引的成本,因为事务必须更新索引。对于事务表,成本效益权衡可能非常微妙,也非常重要。

    如果您的DBMS支持它,那么您可以使用延迟更新对事务表上的一些索引进行有效的更新。

    在任何模式中,至少尝试区分引用表和事务表。我知道,我知道,这有点主观。运用你最好的判断力。

    这取决于流量:并非所有的表都有相同的流量。索引加速了连接和查找。至少,您应该了解DBMS是否有一个优化器,它知道如何根据可用索引和表卷进行合并联接。 如果您不知道什么是合并联接,请了解它是什么。但是不要浪费时间学习如何规划合并加入,除非这是你谋生的方式。

    这取决于紧迫性。在Beckground批处理过程中每月执行一次的查询并不像一个每天能容纳用户1000次的查询那么紧急,而该用户则盯着屏幕,或者上下文切换她的多任务处理。

    当心产品营销会告诉你什么是紧迫性。他们往往会告诉你,在任何情况下,比竞争对手更快都是最紧迫的,即使这意味着在你怀念第一个孩子的时候,工作的晚上和周末也是如此。市场营销通常不关心你是否被烧坏了。他们就像一个骑师,不在乎马是否会再次比赛。事实上,有些交易是非常紧急的,而另一些则相对不重要。

    准备好灵活的指数设计,并考虑权衡。

    我希望我能给你指一本关于这个问题的好书。我希望有人能这样做。

        2
  •  3
  •   Stefan Steinegger    16 年前

    创建索引只有几个经验法则:

    • 在外键上创建索引
    • 在典型的搜索列上创建索引,如用户的登录名和PIN、产品的产品ID等。
    • 不要因为你的想法而创造 能够 提高性能。

    由于应用程序的性能问题,应添加其他索引。

    • 观察应用程序并识别耗时的查询
    • 识别关键查询时,分析执行计划并使用索引对其进行优化。

    在最后一句话中,你说“定义一个合理的模式”。这比如何设计索引要普遍得多。