【CMU 15-445/645 Database Systems】12 Query Processing-1B

538 阅读3分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

Access Methods

DBMS访问表中数据的方法(scan算子)。这里介绍三种方法:顺序扫描,按索引扫描,多索引扫描(也叫bitmap scan)。

Sequential Scan

顺序遍历表的每一个page中的每一个tuple。根据谓词判断是否需要这个tuple。访问每个page的时候,首先检索buffer pool中是否有缓存。DBMS需要维护一个指针(cursor)来标记当前访问到的page/slot。

几乎是最差效率的读取方式。

一些优化方式:

  • prefetching:提前加载后续的pages,避免IO阻塞
  • Parallelization:并行执行scan操作
  • buffer pool bypass: 将page存储在本地内存而非缓冲池中,避免sequential flooding
  • zone map: 预计算每个page的一些聚集计算结果,来粗粒度的判断这个page中是否可能包含所需的数据:

  • late materialization: 每个操作符只将最小的信息传递到下一个(例如record id)。只有列存储系统中有效。
  • heap clustering:

Index Scan

选择一个索引来查找数据。选择索引的依据:

  • 索引包含的属性
  • query需要的属性
  • 属性的值域
  • 谓词组合
  • 索引是否包含non-unique keys

multi-index scan (bitmap scan)

可以用到多个索引的query,流程一般就是如下两步:

  • 从每个匹配的index中查找id set
  • 根据谓词要求对这些set求union或intersect

(在Postgres中叫做bitmap scan)

计算交集,可以使用bitmap,哈希表,布隆过滤器等方法。

很显然的,我们期望尽可能的命中索引,通过索引来进行数据的检索。

index scan page sorting

由于从非聚簇索引(只能检索到tuple存储的位置,不能直接获得数据)中检索到的tuples所分布的pages是混乱的,所以可以先对这些tuples根据它们所属的pages进行排序:

总结

这一节一开始给我唬住了,看完才发现其实就是在讲索引的作用,可能这点平时会熟悉一点,所以很多觉得都是理所应当的不值得专门拎出来说。建立索引当然好,我们期望查询语句尽可能的命中索引,所以一般来说主键是一定要建立索引的,其他的属性上就要看管理员自己的考量了。索引当然也不是越多越好,因为索引越多意味着当表中的数据发生变动的时候,它所需要的维护成本越高。trade-off是一个时刻存在的概念,“均衡,存乎万物之间”。

Expression Evaluation

如上所述,SQL语句会被解析成一棵树:操作符是中间节点,操作数是叶子节点。

构建出表达式树后再进行谓词评估是很慢的,因为DBMS必须遍历树中的节点,并对每个节点要做的事情进行考量。

所以有时候直接判断表达式本身是更好的选择。

JIT

just-in time,在程序启动后,随着程序的运行来逐步进行代码编译(on the fly)。与之对比,传统的编译器会将所有的代码都转化成机器语言,之后才运行程序。