检测并修复 Amazon DocumentDB 中的低基数索引 数据库博客

检测并修复 Amazon DocumentDB 中的低基数索引 数据库博客


检测和修复 Amazon DocumentDB 中的低基数索引

重点内容

在 Amazon DocumentDB 中使用低基数索引可能会导致性能问题。通过积极监测和修复低基数索引,可以提升查询效率。本文将详细介绍如何识别和处理低基数索引,以确保在处理文档数据时性能最优。

Amazon DocumentDB 是一个全面管理的原生 JSON 文档数据库,使得操作关键文档工作负载变得简单且具成本效益,无需管理基础设施。在数据库规模非常庞大的情况下,创建索引可以提升查询性能是一个最佳实践。没有索引的情况下,查询需要更长时间来筛选不符合条件的文档。数据库还应在高基数字段即具有大量唯一值的字段上创建索引。本文将介绍如何在所有 DocumentDB 数据库和集合中主动检测和修复低基数索引。

Amazon DocumentDB 使用 B 树数据结构 来实现其索引。B 树索引采用分层结构,将数据以排序的方式存储在节点中。这种方式保持数据有序,可以高效地进行读取、插入和删除数据。随着新数据的写入,除了修改集合中的文档,索引也会进行更新,这可能会影响写入延迟并增加 IOPS。选择高基数字段即具有大量唯一值的字段可以提高索引选择性;反之,选择低基数字段例如布尔值,仅有两个唯一值可能会检索到多于所需的信息,从而增加内存使用率,甚至导致进入分布式存储卷。索引选择性的目标是让查询尽可能多地提前筛选数据,从而减轻查询处理器的工作负担。

如果您管理着数十个或上百个 Amazon DocumentDB 集群,主动检测和监视基数变化非常重要。虽然在某些情况下,低基数索引可能是必要的,或者集合足够小,以至于不造成任何问题,但在许多情况下,大型集合上的低基数索引会引发性能问题。本文将逐步介绍如何审查和修复已存在的 Amazon DocumentDB 集群中的低基数索引。

啊哈加速器安卓下载

低基数检测工具概述

此工具可以对 DocumentDB 集群中每个集合中样本文档默认为每个索引 10 万进行采样,生成基数报告。用户可以根据此报告,关注低于建议的 1 基数的索引。脚本会对每个集合进行扫描,采集随机样本,根据样本大小和实例类型,可能会影响正在进行的工作负载。您可以在非生产环境中运行此工具,或使用不主动提供流量的读取实例。

该 GitHub 仓库中包含有关如何加载示例数据、创建测试索引和运行基数测试的说明。如果您在自己的集群上运行此工具,可以跳过 README 文件中记录的第 6 步。

以下表格总结了基数测试脚本支持的参数。除 connectionstring 外,其余均为可选参数。默认情况下,基数测试将在所有数据库和集合中运行。您可以通过传入 database 或 collections 参数来缩小测试范围。

参数详细说明默认值uriAmazon DocumentDB 实例的连接字符串。N/Amaxcollections数据库中要扫描的最大集合数。100threshold索引基数阈值百分比。基数低于此百分比的索引将被报告。此值应为数字整数或小数。1databases需检查基数的数据库的命令分隔列表。全部collections需检查基数的集合的命令分隔列表。全部samplecount每个索引的最大采样文档数。增加此限制可能导致更高的 IOPS 成本和延长运行时间。100000

使用基数检测工具的设置和运行

要配置和使用该工具,请执行以下操作:

连接到 Amazon DocumentDB 通过 mongo shell确保您的集合中有索引。您可以在 mongo shell 中执行以下查询:

javascript dbgetCollectionNames()forEach(function(collection) { print(collection db[collection]getIndexes()length count db[collection]count()) })

该输出显示了每个集合的列表,总索引数和总文档数。我们的示例 sampledatabase 只有一个集合 samplecollection,包含 6 个索引和超过 300000 个文档。请注意,其中包括 id 索引,该索引在基数检测中被排除。

从 GitHub 下载项目和 DocumentDB 连接证书

bash git clone https//githubcom/awslabs/amazondocumentdbtoolsgit cd performance/indexcardinalitydetection wget https//truststorepkirdsamazonawscom/global/globalbundlepem

在 Amazon DocumentDB 控制台上查找集群或读取端点。导航到您的数据库,然后选择 Configuration 标签。复制并保存该端点。

运行该工具,替换变量 [DOCDBUSER]、[DOCDBPASS] 和 [DOCDBENDPOINT] 为您的集群信息。

bash python3 detectcardinalitypy uri mongodb//[DOCDBUSER][DOCDBPASS]@[DOCDBENDPOINT]27017/tls=trueamptlsCAFile=globalbundlepem

脚本完成可能需要几分钟。输出将类似于下图:

在本示例中,脚本发现 5 个总索引中的 3 个低于 1 的基数阈值id 索引被忽略。脚本还在当前目录下保存了一个 CSV 文件,其中包含详细报告,如下图所示:

报告显示 CaseType、ProvinceType 和 CountryRegion 是低基数的索引,可能不适合用作索引。

此工具可能会读取大量数据每个索引 100000 个文档,因此建议在 QA 或代表性环境中运行此脚本。为了安全起见,您可以在非高峰时段运行此工具。同时,您也可以 克隆 生产集群并在克隆集群上运行基数检测。

修复低基数索引

本节将解释如何修复通过索引基数检测工具生成的报告中发现的低基数索引。

检测并修复 Amazon DocumentDB 中的低基数索引 数据库博客

删除未使用的索引

索引通常因为需求变化或创建错误而被遗留未使用。亚马逊 DocumentDB 会跟踪索引的使用频率。有关如何查找和删除未使用索引的说明,请参考如何分析索引使用情况并识别未使用的索引?无论索引基数是否较低,建议删除未使用的索引。

如果可能,请构建复合索引

在本文提到的示例中,我们检查了 samplecollection 的索引基数,发现有三个低基数索引:CaseType、CountryRegion 和 ProvinceState。如果用户同时搜索这三者,则构建一个复合索引比添加多个搜索条件更为合理。您可以使用以下代码构建复合索引:

javascriptdbsamplecollectioncreateIndex({ CaseType 1 CountryRegion 1 ProvinceState 1})

为了确保复合索引的有效利用,查询中提供的字段顺序必须与索引的顺序相同。根据集合的大小,索引创建可能需要几分钟到几小时不等。您可以通过增加后台作业的工作线程数量来加快进程,详情见管理 Amazon DocumentDB 索引。成功创建的样子如下图所示:

创建索引后,您可以查看查询的 explain executionStats 状态,以确保索引被使用,nReturned 属性显示较小的数字。

您可以测试类似以下的查询:

javascriptdbsamplecollectionfind({ CaseType Confirmed CountryRegion China ProvinceState Guizhou})explain(executionStats)

前述查询在大规模运行时开销较小。在确认索引已创建后,您可以保留复合索引并删除不再使用的索引。这也有助于减少存储并可能提高数据摄取性能。

清理

以下命令删除在 GitHub 项目说明中创建的数据库、集合和索引。如果您未使用示例数据库,请跳过此测试。

javascriptuse sampledatabase dbdropDatabase()

结论

低基数通常会在您的集合规模增长到数百万文档时造成问题,届时您需要不断扩展实例以满足内存和 CPU 要求。这使得对大型集合进行基数卫生管理变得尤为重要,但即便是小型集合也要保持关注,因为它们未来可能会引发问题。本文解释了如何使用 基数检测脚本 积极监测索引的健康状况,并在基数阈值低于推荐值时回馈给应用团队。

欢迎在评论区留言或反馈您的问题,或者在 GitHub 上创建 issue 提出脚本改进建议。

关于作者

Puneet Rawal 是一名位于芝加哥的高级解决方案架构师,专注于 AWS 数据库。拥有超过 20 年的架构和管理大规模数据库系统的经验。

2026-01-27 14:32:01

将 Amazon RDS for MySQL 和 MariaDB 数据库导出到 Amazon S3,
  • 2026-01-27 14:02:37

将 Amazon RDS 的 MySQL 和 MariaDB 数据库导出至 Amazon S3 的自定义 API 方案关键要点数据库管理员的常见任务是备份生产环境中的数据库,并将其迁移到开发、质量保证...