Warning: Undefined global variable $debug in /var/www/ourcoders/tiny4cocoa/application/controllers/baseController.php on line 124
InfoQ 2019-12-24 21:06:56 发布的技术动态 - OurCoders (我们程序员)
InfoQ
2019-12-24 21:06:56 发布
#小Q分享# 《数据库内核杂谈(七):数据库优化器(上)》:
在上一篇文章中,我们挖了一个坑:在大部分情况下,HashJoin 都是表现最优的,那为什么还需要去支持其他 Join 比如 SortMergeJoin 或者 NestLoopJoin 的算子实现呢?因为不同表的大小,是否有索引支持,以及查询语句是否对某些 column 需要排序都会对执行算子产生影响,从而进一步影响执行时间。就是只看 HashJoin,hash 表到底是对表 A 来建,还是对表 B 来建,也会造成非常大的差别 (通常,我们选取数据量小的表来做 Hash 表,这能使得需要用到的内存更少,更小概率需要借助外部 Hash 表来进行分批次的 join)。而拥有最终决定权的,就是我们今天要聊的主角:数据库优化器 (Query Optimizer)。

首先来谈谈为什么叫优化器。它优化的又是什么呢?最常见的优化指标就是查询语句的运行时间,譬如上述例子中的 HashJoin,优化器选择用数据量小的表来建 Hash 表,运行时间就比选择用大的表要快。那我们再问深一层,为什么对应一个查询语句,可以优化执行时间?归根到底是因为 SQL 是一种 declarative language(声明式语言),它只是告知了数据库系统,它希望数据以什么形式返回,但并没有告诉系统,要怎么去一步一步执行算子来得到最终结果。这和我们通常使用的编程语言是有所不同的。比如用 C 语言写一个冒泡排序和快速排序,虽然最终排序结果一样,但是快速排序确实只用到了更少的比较和交换,所以性能比冒泡排序要快。因为算法交代了应该如何去排序 (当然,编译器还是可以进一步地来优化代码,比如 function-inline,dead code elimination 等等)。这就给了优化器变魔术的空间。
余下全文:网页链接