【问题标题】:Database Optimization techniques for amateurs业余爱好者的数据库优化技术
【发布时间】:2010-04-25 21:18:18
【问题描述】:

我们能否获得一份基本优化技术的列表(从建模到查询、创建索引、视图到查询优化)。最好列出这些,每个答案一种技术。作为一个爱好者,我会觉得这非常有用,谢谢。

为了不太模糊,假设我们正在使用主流数据库,例如 MySQL 或 Oracle,并且该数据库将包含大约 10 个表的 500,000-1m 左右的记录,其中一些具有外键约束,全部使用最典型的存储引擎(例如:InnoDB for MySQL)。当然,还定义了诸如 PK 之类的基础知识以及 FK 约束。

【问题讨论】:

  • 我希望它得到更多的答案。

标签: rdbms-agnostic sql-optimization


【解决方案1】:

了解索引并正确使用它们。一般来说*,请遵循以下准则:

  • 每个表都应该有一个聚集索引
  • 用于过滤器和排序的字段非常适合索引
  • 更多选择性字段更适合索引
  • 为了在关键查询上获得最佳性能,请为这些查询设计“覆盖索引”
  • 确保您的索引确实在使用,并删除那些没有使用的索引
  • 如果您的表有 15 个字段,并且您创建了 15 个索引,每个索引只有一个字段,那么您做错了 :)

*如果您知道自己在做什么,这些规则有一些例外。我的经验是 Microsoft SQL Server,但我认为大部分建议仍适用于不同的 RDMS。

【讨论】:

  • 在可能变大的表上使用聚集索引时应注意一些事项。插入或更新行时,聚集索引可能会导致表重新排序,从而影响性能。
  • 除非您的主键是 GUIDS,否则在这些上使用聚集索引是个坏主意
【解决方案2】:

IMO,到目前为止,最好的优化是让数据模型适合它所构建的问题域。如果不这样做,则产生的症状是难以编写或复杂的查询,以便获得所需的信息,并且通常在针对数据库构建报告时自行恢复。因此,在设计数据库时,了解用户希望从系统获得的信息(例如报告)的类型和性质会有所帮助。

【讨论】:

  • '结果系统'也许?不是“导致症状?”
  • @MJB - 我想我说得对。你怎么知道数据模型不适合问题域?症状复杂或难以编写查询。
  • 我明白了。我看错了。我以为您是在说“生成的系统难以编写”,现在我看到您的意思是“生成的症状是难以编写查询”。我的错。我以为是错字。
  • 是的。通过使用“症状”,他实质上是在说某些迹象(例如复杂的查询)通常表明数据模型不适合问题域。 (+1 顺便说一句)
【解决方案3】:

在谈论数据库设计时,请检查数据库规范化,例如维基百科文章:Normal forms.

如果您的设计不错,但仍需要优化性能,请尝试Denormalisation

如果您有关系模型无法有效涵盖的特定需求,请查看术语 NoSQL 涵盖的其他模型。

【讨论】:

  • 这是一个绝妙的建议 - 标准化并不总是答案!
【解决方案4】:

一些查询/模式优化:

  • 在使用 DISTINCT 或 GROUP BY 时要小心。我发现许多新开发人员会在真正不需要的地方使用 DISTINCT,或者可以使用 Exists 语句或派生查询更有效地重写它。

  • 注意左连接。我经常发现新的 SQL 开发人员会忽略现有的模式,并在真正不需要的地方使用左连接。例如:

Select
From Orders
    Left Join Customers
        On Customers.Id = Orders.CustomerId

如果 Orders.CustomerId 是必填列,则不需要使用左连接。

  • 成为新功能的学生。目前,MySQL 不支持公用表表达式,这意味着某些类型的查询很麻烦,并且可能比支持 CTE 时更慢。然而,这不会永远是真的。跟上 MySQL 中的新语法特性,这些特性可用于提高现有查询的效率。

  • 您不必在任何地方都使用代理键。可能有更适合智能键的表(例如美国州缩写、货币代码等),这将使开发人员在许多情况下避免额外的连接。

  • 如果可能,找到将数据归档到 OLAP 或报告服务器的方法。生产数据越小,运行速度就越快。

【讨论】:

    【解决方案5】:

    简洁地模拟您的问题的设计总是一个好的开始。过度概括数据模型会导致性能问题。例如,我听说过一些项目力求超级灵活性,它们将 RDBMS 用作愚蠢的“名称/价值”存储 - 结果的性能令人震惊。

    一旦有了好的设计,就可以使用 RDBMS 提供的工具来帮助它实现良好的性能。单字段 PK(无复合),但复合业务键作为具有唯一约束的索引,使用适当的数据类型,例如对数值使用适当的数字类型,而不是 char 或类似类型。还应考虑运行 RDBMS 的硬件的物理属性,因为大部分查询时间通常是磁盘 I/O - 但当然不要认为这是理所当然的 - 使用分析器找出时间的去向.

    根据更新/查询比率,物化视图/索引视图可用于提高运行缓慢的查询的性能。穷人的替代方法是使用触发器来调用一个过程,该过程用运行缓慢、不经常更改的视图的结果填充表。

    查询优化有点像黑魔法,因为它通常依赖于数据库,但这里给出了一些经验法则 - Optimizing SQL

    最后,尽管可能超出了您的问题的预期范围,但请在您的应用程序中使用良好的数据访问层,并避免自行推出 - 肯定有适用于所有主要语言的测试和高性能实现。在数据访问层、中间层和应用层使用缓存有助于显着提高性能。

    【讨论】:

      【解决方案6】:

      尽可能使用少查询。使用“JOIN”,并对表进行分组,以便单个查询给出结果。

      Modified Preorder Tree Transversal (MPTT) 就是一个很好的例子,它可以在单个查询中获取所有的树节点父节点。

      【讨论】:

        【解决方案7】:

        采用整体方法进行优化。

        考虑慢速磁盘、网络延迟、内存不足和服务器负载的影响。

        【讨论】:

          猜你喜欢
          • 2010-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多