优化查询性能 - 亚马逊 Quantum Ledger 数据库(亚马逊QLDB)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

优化查询性能

重要

终止支持通知:现有客户可以在2025年7月31日终止支持QLDB之前使用亚马逊。有关更多详细信息,请参阅将亚马逊QLDB账本迁移到亚马逊 Aurora Postgr SQL e。

QLDBAmazon 旨在满足高性能在线事务处理 (OLTP) 工作负载的需求。这意味着QLDB它已针对一组特定的查询模式进行了优化,尽管它支持SQL类似的查询功能。涉及应用程序及其数据模型对于使用此查询模式至关重要。否则,随着表的增长,您将遇到严重的性能问题,包括查询延迟、事务超时和并发冲突。

本节描述了中的查询限制,QLDB并提供了在这些限制条件下编写最佳查询的指导。

事务超时限制

在中QLDB,每个 PartiQL 语句(包括每个SELECT查询)都是在事务中处理的,并且受事务超时限制的约束。在提交之前,事务最多可运行 30 秒。超过此限制后,QLDB拒绝对事务所做的任何工作并丢弃运行该事务的会话。此限制通过启动事务(而不提交或取消事务)以保护服务的客户端免遭泄漏会话。

并发冲突

QLDB使用乐观并发控制 () OCC 实现并发控制。次优查询也可能导致更多冲突。OCC有关 OCC 的信息,请参阅亚马逊QLDB并发模型

最优查询模式

按最佳实践标准,您应运行带有WHERE谓词子句的语句,该子句可以筛选索引字段或文档 ID。QLDB需要在索引字段上使用相运算符(=IN)才能有效地查找文档。

以下是 用户视图 中最佳查询模式的示例。

--Indexed field (VIN) lookup using the = operator SELECT * FROM VehicleRegistration WHERE VIN = '1N4AL11D75C109151' --Indexed field (VIN) AND non-indexed field (City) lookup SELECT * FROM VehicleRegistration WHERE VIN = '1N4AL11D75C109151' AND City = 'Seattle' --Indexed field (VIN) lookup using the IN operator SELECT * FROM VehicleRegistration WHERE VIN IN ('1N4AL11D75C109151', 'KM8SRDHF6EU074761') --Document ID (r_id) lookup using the BY clause SELECT * FROM VehicleRegistration BY r_id WHERE r_id = '3Qv67yjXEwB9SjmvkuG6Cp'

任何不遵循这些模式的查询都会调用 全表扫描。表扫描可能会导致大型表上的查询,或返回大型结果集的查询发生事务超时。它们还可能导致与竞争交易的OCC冲突

高基数索引

我们建议为包含高基数值的字段建立索引。例如,VehicleRegistration表中的 VINLicensePlateNumber 字段是索引字段,旨在保持唯一性。

避免对低基数字段(例如状态代码、地址州或省以及邮政编码)建立索引。如果您为此类字段编制索引,则查询可能会生成较大的结果集,这些结果集更有可能导致事务超时或导致意外冲突OCC

已提交视图查询

您在已提交视图中运行的查询遵循与用户视图查询相同的优化准则。您在表上创建的索引也可用于已提交视图中的查询。

历史记录函数查询

历史记录函数查询不使用您在表上创建的索引。QLDB历史记录仅按文档 ID 编制索引,您目前无法创建其他历史索引。

最佳做法是,使用日期范围(开始时间结束时间)和文档 ID(metadata.id)来限定历史查询。包含开始时间和结束时间的历史记录查询将从日期范围限定中获得便利。

内部联接查询

对于内部联接查询,请使用至少包含联接右侧表的索引字段的联接条件。如果没有连接索引,连接查询将调用多个表扫描 - 对于连接左表中的每个文档,查询将完全扫描右表。除了为至少一个表指定WHERE相等谓词外,最佳做法是对要加入的每个表建立索引的字段进行联接。

例如,以下查询将 VehicleRegistrationVehicle表连接至各自的字段,这两个VIN字段均已编制索引。此查询还有一个VehicleRegistration.VIN相等谓词。

SELECT * FROM VehicleRegistration AS r INNER JOIN Vehicle AS v ON r.VIN = v.VIN WHERE r.VIN IN ('1N4AL11D75C109151', 'KM8SRDHF6EU074761')

为联接查询中的联接条件与相等谓词选择高基数索引。

要避免的查询模式

以下是一些次优语句的示例,这些语句不能很好地扩展到中较大的表。QLDB我们强烈建议您不要依赖这些类型的查询来获取随时间增长的表,因为您的查询最终将导致事务超时。由于表包含大小不同的文档,因此很难为非索引查询定义精确的限制。

--No predicate clause SELECT * FROM Vehicle --COUNT() is not an optimized function SELECT COUNT(*) FROM Vehicle --Low-cardinality predicate SELECT * FROM Vehicle WHERE Color = 'Silver' --Inequality (>) does not qualify for indexed lookup SELECT * FROM Vehicle WHERE "Year" > 2019 --Inequality (LIKE) SELECT * FROM Vehicle WHERE VIN LIKE '1N4AL%' --Inequality (BETWEEN) SELECT SUM(PendingPenaltyTicketAmount) FROM VehicleRegistration WHERE ValidToDate BETWEEN `2020-01-01T` AND `2020-07-01T` --No predicate clause DELETE FROM Vehicle --No document id, and no date range for the history() function SELECT * FROM history(Vehicle)

一般而言,我们不建议在生产用例中运行以下类型的查询模式QLDB:

  • 在线分析处理 (OLAP) 查询

  • 没有谓词子句的探索性查询

  • 报告查询

  • 文本搜索

相反,我们建议将您的数据流式传输到专门构建的数据库服务,该服务针对分析用例进行了优化。例如,您可以将QLDB数据流式传输到 Amazon S OpenSearch ervice,以提供对文档的全文搜索功能。有关演示此用例的示例应用程序,请参阅 GitHub 存储库 aws-sam amazon-qldb-streaming-amazon ples/-。opensearch-service-sample-python有关QLDB直播的信息,请参阅从 Amazon 流式传输日记数据 QLDB

监控性能

QLDB驱动程序在语句的结果对象中提供消耗的 I/O 使用情况和计时信息。您可使用这些指标识别效率低下的 PartiQL 语句。要了解更多信息,请继续 获取 PartiQL 语句统计信息

您还可以使用 Amazon CloudWatch 来跟踪账本在数据操作方面的表现。监控指定LedgerNameCommandTypeCommandLatency指标。有关更多信息,请参阅 使用 Amazon 进行监控 CloudWatch。要了解如何QLDB使用命令管理数据操作,请参阅驱动程序会话管理