首先,parser考虑来自FROM语句的表的引用。他将表的名字规范化为完全确定的格式: server.database.schema.table。可以根据具体情况省略server,database。别名(alias> 也要规范化
规范化表名的作用是为了满足上下文相关的默认规则:允许单部件表名在规范中被使用。
query processor调用catalog manager 来检查表是否已经注册到system catalog。它同时也缓存表的metadata在internal query data structures。
基于表的信息,它使用catalog 来确保属性的引用是正确的。属性的数据类型用来保证重载函数,表达式,操作符,常数计算的规则统一性。
授权检测完成使用者有权限对在query过程中的表,函数,一些对象进行操作。在对statement进行parse的过程中进行完全的授权检测并不总是可行的。我们会将一部分的安全检查延迟在执行过程中。
延迟安全检查的query plan可以和使用者共享,并不会因为安全条件的变化而重新编译。
一些限制性检查, 例如赋值过程中类型不匹配有时也会被延迟到执行期间去做
query rewrite用来简化和标准化query。他利用query和存储在catalog中的metadata进行操作,并不允许访问数据。
query rewrite并不直接对query进行操作,而是对已经parse后的internal format进行操作,query rewrite后的格式与输入前的(internal format)保持一致。
Query rewrite的主要职责: ####1. view expansion(视图扩张) 对于from中出现的视图,rewriter找到catalog 中对应的视图定义,然后重写query,具体流程如下:
query optimizer的工作是将query internal represitation 转换为高效的query plan来执行query.
query plan可以看做一个数据流图来通过query operator 图对数据进行流水线处理。 resulting query plan 可以被以多种方式表示 ####A note on Query compilation and recomplication SQL支持准备一个query, parse, rewrite, optimize,将生成的query plan存储起来,在后续的执行指令中使用它。这甚至可以应用于动态query中,在一个constant query 中有一个 program variable。这样做唯一的缺点是如果optimizer在代替该variable的过程中采用了不好的典型值,会导致生成差劲的query plan。
Query preparation 可用于形成常规的,批发的,数据预测性比较高的的query中,会极大提高效率。
动态构造sql中会更倾向于使用 query plan cache.
query executor 操作于完全特定的query plan。这是一个连接operator的数据流图,其中operator封装了数据的访问和不同的query执行算法。数据流图有俩种表示方法,
Iterator 的一个重要特性是他能够 couple dataflow with control flow.
A single thread can execute an entire query graph.
is quite efficient for single system(non cluster) query execution. 对于 parallel query execution,我们可以将并发和网络传输通过特殊的exchange iterator 封装,无需改变iterator model和query execution arch 就可支持。
每一个iterator 预先分配了一个固定数目的tuple descriptor,一部分用来输入,一部分用来输出,tuple descriptor 由一个列引用的数组构成,每一个列引用由一个指向内存tuple的引用和对应tuple的column offset构成。那么被引用的tuple如何在内存中实际存储呢?
第一类是存储在buffer pool上页中的tuple。如果一个iterator构造tuple descritor 引用BP-tuple,它必须增加相关page的pin count.清除 tuple descriptor 则减少pin count。
第二类一种iterator implementation 可以在堆上开辟tuple的空间来放置tuple,通常通过复制bufer pool的 column或计算表达式来实现。
通常的实现方式是将buffer pool 中的tuple复制到m-tuple中
这种设计采用m-tuple作为唯一的tuple实现,简化执行代码的实现,避免pin 和unpin的bug。但是内存 copy的操作会成为瓶颈。 最好的操作是既使用BP-tuple又使用M-tuple
单独的读和写很容易,但是将读和写结合起来对同一组数据进行操作很难。
举例:
UPDATE EMP
SET salary = salary *1.1
WHERE salary < 200000
这段语句本意是找到小于200000的员工,加一次工资,但是有可能导致已经被update的员工满足条件再次update。
解决该问题的技术
该技术 插入 RECORD-ID materialization和fetching operators 在index scan和data modification之间, 新操作的意义: 将待修改的tuple的RID存储在文件中,扫描文件获得实体ID,将获得的tuple放入 data modification之中。
Access Methods 是控制对基于磁盘的数据结构的访问的程序。他支持unordered files(heap)和各种目录结构
Access Methods 提供的API是iterator API.
Access Methods 的init()方法接受search arg参数SARG,形式为col operator, constant, get_next返回满足参数的tuple。 向access methods传入sarg参数的意义: