关系型数据库工作原理-查询优化器之真实优化器是如何工作的(18)

版权声明:本文为博主原创文章,转载需注明原文链接及作者。 https://blog.csdn.net/ylforever/article/details/79873007

本文翻译自Coding-Geek文章:《 How does a relational database work》。原文链接:http://coding-geek.com/how-databases-work/#Buffer-Replacement_strategies

本文翻译了如下章节, 介绍真实的数据库系统的查询优化器是如何工作的:
这里写图片描述

真实的数据库优化器–Real optimizers

[你可以跳过本章,我下来要描述的东西不重要]

所有之前巴拉巴拉的一堆是非常理论化的。由于我是一个开发人员,不是一个科研人员。我喜欢具体的例子。

让我们看一下SQLite数据库优化器是如何工作的。SQLite是一款非常轻量级的数据库,它使用一种简单的贪婪算法附带一些具体的规则来限制可选策略的数量。
1. SQLite在CROSS JOIN操作中不对表数据排序。
2. 多表连接采用按循环嵌套连接算法。
3. 外连接表总是按它们在SQL语句中出现的顺序处理。
4. …
5. 在3.8.0之前的版本,SQLite使用最近邻居贪婪算法查找最优的算法计划。
稍等,我们已经讲过这个算法。巧合的是:
6. 从3.8.0版本(发布于2015年),SQLites使用最近邻居贪婪算法查找最优算法路径(译者:迷糊了,还是作者写错了?)。

让我们再看另外一款数据库优化器是如何做的。IBM DB2跟所有的企业级数据库一样,但是我重点介绍一下这一款。因为它是我转向大数据领域前最后使用的一款企业级数据库。

如果我们看了DB2的官方手册,我们就知道DB2优化器可以设置7种不同级别的优化等级。

在表连接时使用贪婪算法。

  • 0-最小程度的优化,使用索引扫描和循环嵌套连接,避免查询重写。
  • 1 低级别的优化。
  • 2 完全优化。
  • 3 在表连接时使用动态规划算法
  • 4 适度的优化,取初略的近似值。
  • 5 完全优化,使用所有的启发式算法。
  • 6 完全优化,跟上面一条类似,但是不使用启发式算法。
  • 7 最大程度优化,不计成本考虑所有可能连接顺序,包括计算笛卡尔集(所有的排列组合)。

我们看到DB2使用了贪婪算法和动态规划算法。当然,他们没有共享他们使用的具体算法细节,因为查询优化算法是数据库的核心能力。

FYI,DB2默认的优化级别是5。默认数据库优化器使用下面这些特性:
1. 所有现有的统计数据,包括值出现的频率,次数等都会被用到。
2. 所有的查询重写规则(包括具体的表查询线路),除了一些很少的无法计算结果的很少的场景(译者注:作者的意思可能是说计算工作量很大,或者本身NP问题)。
3. 使用到了动态规划连接穷举算法,带限制条件:
4. 限制内连接表组的组合应用方式。
5. 受限的笛卡尔集计算,在查询表的星型模型中。
6. 考虑更广泛的数据获取方式,包括列表数据预取,索引合并和具体的表查询路径。

默认DB2使用动态规划算法仅限在处理表连接顺序上。

查询计算缓存-Query Plan Cache

由于创建一个查询计划需要不少时间,大多数数据库将存储查询计划数据放到缓存中,避免在多次相同的查询中重复计算。

这也是一个很大的问题,数据库要考虑何时更新过期的查询计划。一种方法是设置一个阈值,如果数据库表的统计值发生改变超过阈值时,清空缓存刷新数据。

查询执行器–Query executor

到这个阶段,我们已经拥有了一个优化后可执行的查询计划。这个查询计划被编译为可执行的代码。

如果有足够的资源(内存,CPU),它将被执行器执行。

操作语句中的计划(JOJN,ORDER BY…)将被串行或者并行的执行。

为从数据库读或者写数据,查询执行器将与数据管理器交互。这是下一章节的内容。

FYI: 翻译完了,看了最早的一篇翻译是两年前的,这两年感慨良多。

猜你喜欢

转载自blog.csdn.net/ylforever/article/details/79873007