13

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

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

4

7 回答 7

15

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

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

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

于 2010-05-11T22:10:59.630 回答
7

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

于 2010-04-25T22:07:05.530 回答
5

在谈论数据库设计时,请查看数据库规范化,例如 wikipedia 文章:Normal forms

如果您有一个好的设计,但仍然需要优化性能,请尝试Denormalisation

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

于 2010-04-25T21:22:40.450 回答
3

一些查询/模式优化:

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

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

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

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

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

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

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

于 2010-05-15T03:57:02.277 回答
2

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

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

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

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

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

于 2010-05-14T19:51:22.483 回答
1

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

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

于 2010-05-18T11:52:23.280 回答
0

采取整体方法进行优化。

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

于 2010-05-18T11:34:29.800 回答