前言 随着行动使用者的高速发展,「资料」已成为当今最宝贵的资源;谁掌握了资料,谁就掌握无尽的宝藏。而如何有效地管理这些巨量资料则成为首要问题。从电脑出现以来,人们便孜孜不倦地追求着高效管理资料的办法, IBM的System R,U. C. Berkeley PostgreSQL以及Oracle MySQLOracle的诞生,无一不表明人们对于高效、快速的资料管理的不懈追求。
虽然Oracle、MySQL广泛应用于国内外各大网际网路公司的基础架构中,但作为另一款优秀的开放原始码关联式资料库,PostgreSQL同样也获得各大网际网路公司的持续关注;另外随着大数据平台对SQL标准支援的日益丰富,SQL on Hadoop的各种解决方案如雨后春笋般涌现,例如Hadoop Hive、Facebook Presto、Cloudera Impala等,这些SQL on Hadoop解决方案无一例外地需要一个表现优异的SQL查询引擎的支援。
作为资料库的大脑,查询引擎的优劣直接决定了资料库管理系统的好坏。不同的查询引擎对相同查询叙述的处理策略可能截然不同,而其导致的执行效率也差别很大,少则相差数倍,多则数百倍。因此,认真地分析设计优秀的查询引擎并学习其查询最佳化方法,可以使我们能够以「巨人肩膀之上」的方式来提升我们自己资料库产品的查询效率。
PostgreSQL为优秀的开放原始码关联式资料库管理系统,其来自U.C Berkeley,带有浓郁的学术气息,资料库相关理论贯穿于整个PostgreSQL的设计和实现中,尤以查询引擎更甚。无论中文或是英文资料,对PostgreSQL查询引擎的介绍非常缺乏,仅有的相关资料不是限于整体架构性的介绍,就是粗浅的概述性描述。对PostgreSQL查询引擎中较多的实现及其相对应的理论基础并无较为深入的说明,这使得很多相关核心开发人员初次阅读查询引擎原始程式时存在许多的学习困难和疑点。举例来说,查询引擎在子连结处理时的理论依据;Lateral Join的处理方法;限制条件下推时需满足的条件;选择率对查询计画的影响等。而这也正是作者最初在阅读PostgreSQL查询引擎原始程式时所经历过的迷惑和不解。
本书的写作初衷正是为了加快资料库开发人员对PostgreSQL查询引擎的学习过程以及减少相关人员在原始程式学习中的迷惑,同时本书也为那些想一窥查询引擎究竟的DBA们提供一个相互学习的机会和通道,无论你是MySQL DBA或是Oracle DBA。
读者定位
本书尝试以一种全新的角度列出对LPostgreSQL查询引擎的分析,笔者作为一名资料库核心开发人员,了解核心开发人员关注的重点是什么。因此,本书以一位核心开发人员和架构师的角度来探讨如何设计并完成一个资料库查询引擎;资料库查询引擎在设计和实现过程中需要考虑哪些问题,又透过什么样的途径和方法来解决这些问题。举例来说,如何以资料结构来表示一条SQL查询叙述?如何将SQL查询最佳化理论应用到查询引擎的实现中?相信读者在阅读本书后,能产生同样的思考。
本书主要针对的读者:首先是资料库核心开发人员。无论你是MySQL开发人员还是PostgreSQL开发人员,亦或是Infomix开发人员。一个优秀的查询引擎总是值得你花费一定的时间和精力进行研究并学习其设计和实现中的精华。其次,资料库DBA们同样也值得花费一定的时间和精力来阅读和研究查询引擎原始程式,所谓知彼知己,百战百胜。只有更进一步地了解核心中的理论基础和实现机制,我们才可能管理好资料库。最后,对于那些对资料库核心实现有兴趣的相关人员,无论您是经验丰富的老手还是初出茅庐的新手,我想本书也能够为想要了解PostgreSQL查询引擎的实现内幕的您提供一丝帮助。同样,对于高年级的大学生或是低年级的所究所学生,相信本书也可作为您学习资料库理论的有益补充。
当然,您在阅读本书之前还需要有一些必要的知识:对SQL标准有必要的认识和了解;了解资料库原理中的相关基本概念,例如查询计画、索引等;C/C++程式设计知识等。
章节编排
第1章以如何了解并执行查询叙述为例,综合性地描述PostgreSQL查询引擎包含的相关模组以及各个模组的功能。
第2章从核心开发人员的角度出发重点介绍描述一条SQL查询叙述需要的相关资料结构。
第3章主要讨论对一条SQL查询叙述的识别以及相关知识,并以此为基础重点讨论将该字串形式的SQL查询叙述转为查询树的过程。
第4章将以第3章中所获得的查询树为基础,讨论如何对该查询树进行查询逻辑最佳化。举例来说,对SubLinks的最佳化处理,对SubQueries的处理,对运算式的最佳化,对限制条件的处理,对Lateral Join的的处理,等等。
第5章以查询中有关的基底资料表的物理参数为基础,依据查询代价来计算查询叙述的最佳查询存取路径的方法,并对实体最佳化中使用的相关技术和理论基础进行详细的讨论和分析。举例来说,所有可行查询存取路径的求解策略,多表连接的处理策略,索引建立和选择的策略,实体代价相关参数的分析,等等。
第6章以第5章中所获得的最佳查询存取路径为基础,重点讨论如何依据该查询存取路径建置执行引擎所需的查询计画。例如,顺序扫描查询计画的建置,连接关系查询计画建置等。
第7章主要分析我们在原始程式阅读过程中遇到的一些重要辅助函数。
错误说明
由于笔者水准有限,在本书中会存在一定的错误,例如笔误、了解错误等,对于本书中出现的错误,读者可以在www.leehao.orgorg中查询该错误的勘误资讯,或发送邮件至hom.lee@hotmail.com与作者联系。笔者非常希望能够与读者共同进步,共同推动资料库核心开发人员对PostgreSQL查询引擎的认识。相比MySQL而言,PostgreSQL的相关资料非常少,而专门介绍PostgreSQL查询引擎之类的资料则更加少,这也是本书成书的原因。
学习资料
原始程式码作为最好的学习资料,应该永远值得我们认真对待和重视,本书所有分析均基于PostgreSQL9.4.1版本。读者可以在github.com/postgres中下载最新原始程式。当然,最新版本的原始程式可能与本书讨论中列出的原始程式有所不同,但这并不影响我们对主题问题的讨论。
为了解最新特性或想参与PostgreSQL核心开发,读者可以订阅PostgreSQL邮寄清单,其中包含开发人员邮寄清单、当地语系化相关邮寄清单、相关Bugs邮寄清单等。
■ www.postgresql.org/list/pgsql-cluster-hackers/ 丛集相关核心开发人员邮寄清单;
■ www.postgresql.org/list/pgsql-committers/ 核心commiters 邮寄清单,为核心日常技术问题讨论,读者可从中了解核心commiters 的最新动态;
■ www.postgresql.org/list/pgsql-hackers/ 核心开发人员邮寄清单;
■ www.postgresql.org/list/pgsql-interfaces/ 相关介面讨论邮寄清单,例如odbc、jdbc 等;
■ www.postgresql.org/list/pgsql-docs/ 相关文件邮寄清单;
■ www.postgresql.org/list/pgsql-bugs/ 相关bugs 邮寄清单。
相关邮寄清单并不限于上述几种, 实际内容还请读者参考www.postgresql.org/list/ 中列出的详细资讯。
致谢
本书在撰写过程中获得了许多朋友的关心和帮助。首先,感谢北大方正资讯产业集团基础软体中心(上海)的同伴们:王博、王鑫、蒋灿、彭川、罗正海、黄诚一、刘慧娟、何奇、刘钰,等等。正是他们的鼓励和帮助,我才有完成本书的勇气和动力。同时,还要感谢基础软体中心(上海)关健和陈敏敏两位主管。
腾讯TDSQL 技术专家赵伟、Oracle MySQL 技术专家赖铮阅读了本书的书稿并列出了许多具有洞察力的建议和意见。两位专家作为我的好友,其毋庸置疑的技术能力和为人、做事一直是我前进路上的榜样。在此,对二位的鼓励表示真挚的感谢。
由书稿到铅字出版,离不开本书的责任编辑博文视点陈晓勐编辑的辛勤工作。无论从本书主题、版式风格,到稿件的修改等诸多方面,在此表示衷心感谢。
同样要对我成长路上的诸多师长和同学及友人表达最衷心的感谢,正是他们的谆谆教诲和陪伴,我才可以自由地追逐梦想。
李浩