高级查询优化

28 Aug 2024 | 5 分钟阅读

各种主题将查询优化提升到高级水平。

在本节中,我们将讨论其中的几个主题。

Top-K 优化

数据库系统用于从中获取数据。但用户提供的一些查询会按照某些属性对结果进行排序,并且只需要 K 个最佳结果。此外,一些查询支持 bound K 或 limit K 子句,用于获取前 K 个结果。但是,有些查询不支持 bound K。对于这些查询,优化器会指定一个提示,指示查询检索到的结果仅为前 k 个结果。即使查询生成了更多结果,包括前 k 个结果,也没有关系。在 K 值较小的情况下,即使查询优化计划生成了整个结果集,对其进行排序并生成前 K 个结果,这样做也是无效且效率低下的,因为它可能会丢弃大部分计算出的中间结果。因此,我们使用多种方法来优化此类 top-k 查询。

两种方法是:

  • 使用流水线查询评估计划以排序的顺序生成结果。
  • 估算出现在前 K 个结果中的排序属性的最高值,并引入用于消除较大值的选择谓词。

无论如何,会生成一些超出前 K 个结果的额外元组。这些元组会被丢弃,如果生成的元组太少,不足以达到前 K 个结果,那么我们需要重新执行查询,并且需要更改选择条件。

连接最小化

有不同的连接操作用于处理给定的用户查询。通过视图生成的查询,为了计算查询,需要连接比实际要求更多的关系。为了解决这种情况,我们需要从连接中删除这些关系。这种解决方案或方法称为 **连接最小化**。我们只讨论了其中一种情况。还有更多类似的情况,我们也可以在那里应用连接最小化。

更新优化

更新查询用于更改已持久化的数据。更新查询通常在集合和 where 子句中包含子查询。因此,在优化更新时,也必须包含这两个子查询。 **例如**,如果用户想更新 *student* 表中 *roll_no* 为 102 的学生的 *score* 为 97。将使用以下更新查询:

update student set score = 97 where roll_no = 102

但是,如果更新涉及对更新列的选择,我们需要小心处理此类更新。如果在索引扫描期间进行了更新,那么我们需要在扫描之前将更新后的元组重新插入到索引中。此外,更新受影响的子查询可能会出现一些问题。

万圣节问题 (Halloween Problem)

这个问题之所以得名,是因为它最早是在 **IBM** 的万圣节当天被发现的。更新影响与更新相关的查询执行的问题,称为 **万圣节问题**。但是,我们可以通过执行以下步骤来避免此问题:

  • 首先执行定义更新的查询
  • 创建一个受影响元组的列表
  • 最后,更新元组和索引。

因此,遵循这些步骤会增加查询评估计划的执行成本。

我们可以通过检查是否可能发生万圣节问题来优化更新计划,如果不会发生,则在查询处理过程中执行更新。这确实减少了更新开销。我们可以通过一个例子来理解这一点,*假设如果索引属性不受更新影响,则万圣节问题不会发生。但是,如果更新也减少了值,即使索引按升序扫描,在这种情况下,它在扫描过程中也不会再次遇到更新后的元组。但在这种情况下,即使查询正在执行,它也可以更新索引。因此,这将降低总体成本并导致优化的更新。*

另一种优化此类导致大量更新的更新查询的方法是 **将所有更新收集为一个批次**。收集后,将这些批次更新单独应用于每个受影响的索引。但是,在将更新批次应用于索引之前,需要按索引顺序对批次进行排序。因此,这种批次的排序将减少更新索引所需的大量随机 I/O。

因此,我们可以在大多数数据库系统中执行此类更新优化。

多查询优化和共享扫描

我们可以将多查询优化理解为用户提交一批查询。查询优化器利用不同查询之间的公共子表达式。它这样做是为了评估一次并随时重用它们。因此,即使是复杂的查询,我们也可以利用子表达式,并相应地降低查询评估计划的成本。因此,我们需要为不同的查询优化子表达式。一种优化方法是消除公共子表达式,称为 **公共子表达式消除**。公共子表达式消除方法通过计算并存储结果来优化子表达式。进一步,在子表达式出现时重用结果。只有少数数据库会对为每个查询批次选择的评估计划之间的公共子表达式进行利用。

在某些数据库系统中,实现了另一种形式的多查询优化。这种实现形式称为 **查询之间的关系扫描共享**。了解以下步骤以了解共享扫描的工作原理:

  • 它不会重复地从磁盘读取关系。
  • 对于每个需要扫描关系的查询,它只从磁盘读取一次数据。
  • 最后,它将数据流水线传输给每个查询。

当多个查询扫描事实表或单个大关系时,这种共享扫描优化方法很有用。

参数化查询优化

在参数化查询优化方法中,查询优化是在不指定其参数值的情况下进行的。优化器为不同的参数值输出多个最优计划。只有当计划对某些可能的参数值最优时,它才会输出该计划。之后,优化器存储一组备用计划。然后找到并选择最便宜的计划。这种选择所需的时间比重新优化过程少得多。这样,优化器就优化了参数,并产生了优化且成本效益高的输出。


下一个主题转换关系表达式