分享到

简介

如果您的应用程序速度变慢,则很可能问题与您的数据库相关 - 至少部分相关。

了解到您的应用程序的性能问题可能与数据库有关,这是减少延迟的良好第一步。棘手的部分是找出这些瓶颈可能存在于哪里为什么

本文介绍了一些在数据库中造成性能瓶颈的最常见问题,以及可以采取的一些补救措施。

数据库日志和指标

如果不查看日志,则无法诊断数据库中的瓶颈。大多数云提供商为您提供丰富的信息来评估您的查询正在发生的情况,但可能很难知道这些信息在说什么。

探索日志、指标和查询统计信息

大多数云数据库提供商,包括 DigitalOcean、AWS、Google Cloud Platform、MongoDB Atlas 等,都提供一个查看日志的位置。重要的是要熟悉此日志信息的布局和结构,以便您可以更轻松地在以后找到问题。

例如,DigitalOcean 提供了一个名为“Logs & Queries”的选项卡,可以直接从部署管理菜单访问。

DigitalOcean Logs & Queries Menu Item

在本节中,有一个名为“Recent Logs”的子部分,它提供日志信息的实时显示。

DigitalOcean Recent Logs section

这些日志中包含的信息可能对您尝试排除故障的特定瓶颈问题有用,也可能没有用。但是,某些信息(例如会话持续时间)可能会指示长时间连接到数据库的会话。

探索指标仪表板

云数据库提供商的指标仪表板可让您最深入地了解您可能遇到的瓶颈。大多数云提供商都会显示与性能相关的信息,例如

  • 系统和进程 CPU 使用率
  • 缓存使用率
  • 内存
  • 连接数

查看系统 CPU 使用率等项目的指标可能会揭示与资源约束相关的问题。您可能会看到与执行备份等管理任务相关的使用率峰值。持续的高使用率可能表明您的数据库服务器配置不足。

探索查询统计信息

来自云数据库提供商的查询统计报告可能是确定减速来自何处的最佳信息来源。在许多情况下,减速可以追溯到执行时间长的查询。

提供商之间报告查询统计信息的方式有所不同,但在大多数情况下,提供商都有一种方法来显示被认为速度慢的查询。大多数提供商都会显示查询语句、调用次数以及该特定查询的计时。

例如,DigitalOcean 的查询统计信息以表格格式显示此信息。

DigitalOcean Query Statistics section

未索引的表

数据库表的索引在概念上类似于书中的索引。如果书中没有索引,您只能浏览每一页来查找您感兴趣的主题。相反,如果这本书有索引,您可以先在索引中搜索特定主题,然后您将被指向正确的页码。这大大减少了查找您要查找的信息所需的时间。

相同的概念应用于数据库索引。向数据库表添加索引可以实现快速查找。

如果您从表中少量数据开始,通常不会立即注意到与索引相关的问题。但是,随着数据的增长,缺乏索引可能会变得更加明显。

为您的表创建索引

数据库表的索引需要根据常见的访问模式创建。创建索引时,您需要指定索引应基于的列或字段。

例如,如果您的表在 users 表中有一个 email 字段,则您的应用程序中可能有一个查询根据用户的电子邮件搜索用户。如果没有索引,查询将搜索整个表以查找正确的记录。相反,如果您在 email 字段上创建索引,查询将首先查阅索引以查找电子邮件值。找到后,它将指向该用户的特定数据库行。

识别添加索引机会的最佳方法是查找哪些查询执行时间较长。此信息可以在云提供商数据库仪表板的“Query Statistics”(或类似部分)中找到。

在所有其他条件相同的情况下,最好首先关注最慢报告的查询,方法是为正在使用的访问模式添加索引。然后,您可以向下移动列表,在需要的地方添加索引,直到慢速查询得到解决。

可以使用原始 SQL 创建索引。虽然具体细节因使用的特定数据库而异,但创建索引的 SQL 命令可能如下所示

CREATE INDEX email_index ON users (email);

索引就位后,随着时间的推移检查您的查询统计信息,以查看性能是否有所提高。

使用 EXPLAIN 检查慢速查询

在某些情况下,云数据库提供商的查询统计信息仪表板可能无法为您提供足够的信息。它可能会向您显示哪些查询速度慢,但可能不清楚应该创建哪些索引,或者应该如何优化您的查询。

对于这些情况,您可以选择使用 EXPLAIN 语句检查您的查询。此语句与您的常规查询结合使用,可用于获取有关查询执行计划的详细信息。

例如,在 PostgreSQL 中,在常规查询之前使用的 EXPLAIN 语句将生成如下信息

  • 估计的启动成本
  • 估计的总成本
  • 估计的输出行数
  • 行的平均宽度(以字节为单位)

例如,以下 EXPLAIN 的用法

EXPLAIN SELECT * FROM users;

将生成此报告

QUERY PLAN
-------------------------------------------------------------
Seq Scan on users (cost=0.00..458.00 rows=10000 width=244)

EXPLAIN 语句是深入研究特定查询并分析其成本的宝贵工具。从使用 EXPLAIN 收集的信息超出了云提供商在查询统计报告中提供的信息,可用于优化您的查询。

大数据量

未优化的查询或范围过广的查询可能会从数据库返回异常大的数据量。当从具有最少数据的新数据库开始时,通常很难检测到此问题,但是随着数据库大小的增长,它很可能会导致问题。

当从查询返回大量数据时,需要将其扫描到数据库服务器上的内存中。这可能会导致 CPU 峰值和对突发模式使用的需求。这可能会导致数据库服务器崩溃。如果数据是从数据库服务器返回的,那么如果您的应用服务器配置不足,数据也可能对于您的应用服务器来说太大而无法处理。

解决数据过度获取问题需要优化查询,将选择范围限定为相关记录。解决方案通常是使用 WHERE 子句,但您首先需要找到导致问题的查询。

您的云数据库提供商日志和指标可以指示从数据库返回了大量数据。您可能会看到突发信用使用或 CPU 峰值。但是,可能很难仅从这些指标中判断出哪些查询是罪魁祸首。

应用服务器中的检测

为了全面了解哪些查询导致返回大量数据,您可以向应用服务器添加检测。New Relic、Datadog 和 Dynatrace 等工具可以监控您的应用服务器并报告数据在通过时的大小。查找应用服务器的哪些端点或区域正在处理大量数据可以帮助您找出哪些数据库查询可能是罪魁祸首。

查询优化

查询优化不是一劳永逸的,并且很大程度上取决于具体情况。但是,有一些常见的优化类型应考虑。

  • 限定查询范围以防止过度获取 - 确保在适用时使用 WHERE 子句以减少返回的数据总量。
  • 仅选择所需的字段 - 在许多情况下,并非需要表中的所有字段来满足您的应用程序。仅选择您的应用程序所需的特定字段,以防止过度获取。
  • 审核您的模式 - 检查您的数据库模式,以寻找减少复杂性的机会。依赖于许多连接的查询通常运行缓慢,可以通过调整您的模式以减少关系来改进。
  • 使用数据库视图 - 视图类似于表,但通过运行查询预先生成,以预先计算可能在运行时派生的值。视图有其自身的注意事项,并非适用于所有应用程序和用例。

结论

应用程序性能不佳通常可以追溯到数据库问题。通常,这些问题与次优查询有关。

没有优化查询的万能方法。但是,努力分析和检查某些查询在何处以及为何性能不佳,有助于找出应调整的特定查询。一旦确定,对查询进行调整,例如添加索引、使用 WHERE 子句限定范围以及选择所需字段,可以产生更好的性能。

关于作者
Ryan Chenkie

Ryan Chenkie

Ryan 是一名全栈开发人员,对数据库和 API 特别感兴趣。他是 CourseLift 的创始人,CourseLift 是一个课程托管平台,可帮助作者进行营销和销售。
Daniel Norman

Daniel Norman

Daniel 是一名软件工程师,在现代 Web 和云环境方面拥有广泛的经验。他从事数据库开发已有 15 年以上,并且对开源和现代开发工具充满热情。