简介
如果您的应用程序变慢了,很有可能问题与您的数据库有关(至少部分如此)。
知道您的应用程序性能问题可能涉及数据库是减少延迟的第一步。棘手的部分是找出这些瓶颈可能存在于何处以及为何。
本文涵盖了在数据库中造成性能瓶颈的一些最常见问题以及可以采取的一些补救措施。
数据库日志和指标
如果不查看日志,就无法诊断数据库中的瓶颈。大多数云提供商都提供丰富的信息,供您评估查询的运行情况,但可能很难理解这些信息在说什么。
探索日志、指标和查询统计信息
大多数云数据库提供商,包括 DigitalOcean、AWS、Google Cloud Platform、MongoDB Atlas 等,都提供查看日志的位置。熟悉此日志信息的布局和结构非常重要,这样您就可以在以后更容易地发现问题。
例如,DigitalOcean 提供一个名为“日志和查询”的选项卡,可以直接从部署管理菜单访问。
在此部分中,有一个名为“最新日志”的子部分,提供日志信息的实时显示。
这些日志中包含的信息可能对您尝试解决的特定瓶颈问题有用,也可能没用。但是,某些信息(例如会话持续时间)可能会指示会话连接到数据库的时间过长。
探索指标仪表板
您的云数据库提供商的指标仪表板为您提供了对可能遇到的瓶颈的最大洞察力。大多数云提供商会显示与性能相关的信息,例如:
- 系统和进程 CPU 使用率
- 缓存使用率
- 内存
- 连接数
查看系统 CPU 使用率等项目的指标可能会揭示与资源限制相关的问题。您可能会看到与执行备份等管理任务相关的使用率峰值。持续高使用率可能表明您的数据库服务器配置不足。
探索查询统计信息
您的云数据库提供商的查询统计报告可能是确定减速来源的最佳信息来源。在许多情况下,减速可以追溯到执行时间长的查询。
不同提供商报告查询统计信息的方式不同,但在大多数情况下,提供商都有办法显示被认为是慢速的查询。大多数提供商会显示查询语句、调用次数以及该特定查询的时间。
例如,DigitalOcean 的查询统计信息以表格形式显示此信息。
未索引的表
数据库表的索引在概念上类似于书中的索引。如果没有书中的索引,您就必须翻阅每一页才能找到您感兴趣的主题。如果书中有索引,您可以先在索引中搜索特定主题,然后它会指向正确的页面。这大大减少了查找所需信息所需的时间。
同样的概念也适用于数据库索引。向数据库表添加索引可以实现快速查找。
如果您的表一开始只有少量数据,通常不会立即注意到与索引相关的问题。然而,随着数据的增长,缺乏索引会变得更加明显。
为您的表创建索引
数据库表的索引需要根据常见的访问模式创建。创建索引时,您需要指定索引应基于的列或字段。
例如,如果您的表在 `users` 表中有一个 email 字段,您的应用程序中可能有一个根据用户电子邮件搜索用户的查询。如果没有索引,查询将遍历整个表以查找正确的记录。相反,如果您在 email 字段上创建索引,查询将首先查询索引以查找电子邮件值。找到后,它将指向该用户的特定数据库行。
识别添加索引机会的最佳方法是查找哪些查询执行时间很长。此信息可以在您的云提供商数据库仪表板的“查询统计信息”(或类似)部分中找到。
在所有其他条件相同的情况下,最好首先通过为正在使用的访问模式添加索引来关注报告的最慢查询。然后,您可以向下遍历列表,在需要的地方添加索引,直到慢速查询得到解决。
索引可以通过原始 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 子句限制范围以及选择所需字段,可以显著提高性能。
如果您正在使用 Prisma,您可以在我们的性能和优化文档中了解如何衡量和优化您的查询。




