本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
优化 CloudTrail Lake 查询
本页提供有关如何优化 CloudTrail Lake 查询以提高性能和可靠性的指导。它涵盖了特定的优化技术以及常见查询失败的解决方法。
优化查询的建议
请按照本节中的建议来优化您的查询。
优化聚合
在GROUP BY子句中排除冗余列可以提高性能,因为更少的列需要更少的内存。例如,在下面的查询中,我们可以在冗余列上使用该arbitrary函数eventType来提高性能。on arbitrary 函数eventType用于从组中随机选择字段值,因为该值是相同的,不需要包含在GROUP
BY子句中。
SELECT eventName, eventSource, arbitrary(eventType), count(*) FROM $EDS_ID GROUP BY eventName, eventSource
通过按其唯一值计数(基数)的降序对GROUP BY中的字段列表进行排序,可以提高GROUP BY函数的性能。例如,在获取每种类型的事件数量时 AWS 区域,可以通过在函数中使用eventName、awsRegion顺序来提高性能awsRegion,eventName因为的唯一值eventName比GROUP
BY函数的唯一值多awsRegion。
SELECT eventName, awsRegion, count(*) FROM $EDS_ID GROUP BY eventName, awsRegion
使用近似技术
每当不需要精确的值来计算不同值时,请使用近似聚合函数approx_distinctCOUNT(DISTINCT fieldName)操作快。
限制查询结果
如果查询只需要示例响应,则使用LIMIT条件将结果限制为少量行。否则,查询将返回较大的结果,并且需要更多时间来执行查询。
与LIMIT一起使用ORDER BY可以更快地提供排名前或后 N 条记录的结果,因为它可以减少所需的内存量和排序所花费的时间。
SELECT * FROM $EDS_ID ORDER BY eventTime LIMIT 100;
优化 LIKE 查询
您可以使用 LIKE 来查找匹配的字符串,但是对于长字符串,这将占用大量计算资源。在大多数情况下,该regexp_like
通常,您可以通过锚定要查找的子字符串来优化搜索。例如,如果您要查找前缀,则最好使用' substr %'代替LIKE运算符的'%% substr ',在函数中使用'^substr'。regexp_like
使用 UNION ALL 代替 UNION
UNION ALLUNION还有两种方法可以将两个查询的结果合并为一个结果,但UNION会删除重复的结果。 UNION需要处理所有记录并找到重复项,这需要占用大量内存和计算,但操作速度相对UNION ALL较快。除非需要对记录进行重复数据删除,否则请使用 UNION ALL 以获得最佳性能。
仅包含必需列
如果您不需要一列,请不要将其包含在查询中。查询需要处理的数据越少,运行速度就越快。如果您在最外层的查询SELECT
*中存在查询,则应将更改*为所需的列列表。
ORDER BY 子句按排序顺序返回查询结果。对大量数据进行排序时,如果所需的内存不可用,则中间排序的结果将写入磁盘,这可能会减慢查询的执行速度。如果您不严格要求对结果进行排序,请避免添加 ORDER
BY 子句。此外,如果不是绝对必要,请避免将其添加到ORDER BY内部查询中。
缩小窗口函数范围
窗口函数PARTITION BY子句来减小窗口函数操作的窗口的大小。
有时,使用窗口函数的查询可以在没有窗口函数的情况下重写。例如,你可以使用row_number或之类的聚合函数rank,而不是使用max_bymin_by
以下查询使用查找最近分配给每个 KMS 密钥的别名max_by。
SELECT element_at(requestParameters, 'targetKeyId') as keyId, max_by(element_at(requestParameters, 'aliasName'), eventTime) as mostRecentAlias FROM $EDS_ID WHERE eventsource = 'kms.amazonaws.com' AND eventName in ('CreateAlias', 'UpdateAlias') AND eventTime > DATE_ADD('week', -1, CURRENT_TIMESTAMP) GROUP BY element_at(requestParameters, 'targetKeyId')
在这种情况下,该max_by函数返回记录的别名,其中包含组内最新的事件时间。与使用窗口函数的等效查询相比,此查询运行速度更快,占用的内存也更少。
查询失败的解决方法
本节提供了常见查询失败的解决方法。
由于响应太大,查询失败
如果响应过大,导致出现消息,则查询可能会失败Query response is too large。如果发生这种情况,您可以缩小聚合范围。
诸如此类的聚合函数array_agg可能导致查询响应中至少有一行非常大,从而导致查询失败。例如,由于所选 CloudTrail 事件的事件名称重复,使用array_agg(eventName)代替array_agg(DISTINCT
eventName)会大大增加响应大小。
由于资源耗尽,查询失败
如果在执行诸如联接、聚合和窗口函数之类的内存密集型操作期间没有足够的内存,则中间结果会溢出到磁盘,但是溢出会减慢查询的执行速度,并且可能不足以防止查询失败。Query exhausted
resources at this scale factor可以通过重试查询来修复这个问题。
如果即使在优化查询后仍存在上述错误,则可以使用事件缩小查询范围,并在原始查询时间范围的较小间隔内多次执行查询。eventTime