Sargable 与 谓语下推 (predicate pushdown) 简介
关键词:SQL优化 , sargable , pushdown filter , predicate pushdown
Sargable
Sargable = Search ARGument ABLE ,即SQL中可利用数据库自身索引优势对查询条件进行执行性能优化。换句话说,即可以利用存储层的索引优势来优化的查询条件。wikipedia: https://en.wikipedia.org/wiki/Sargable
典型的案例就是SQL中的WHERE条件,一个条件单元一般是一个函数作用于一个列/字段的数据;ORDER BY, GROUP BY, HAVING 等有时候也可Sargable。
- Sargable operators: =, >, <, >=, <=, BETWEEN, LIKE, IS [NOT] NULL
- Sargable operators that rarely improve performance: <>, IN, OR, NOT IN, NOT LIKE
通常一个操作是否可Sargable比较好判断,当你足够了解存储层,你便知道这个操作是否可以转化为基于索引的查询或变成一些谓语下推(pushdown filter) 的方式。
但是多个操作联合的时候就麻烦了,多个操作的逻辑联合主要包括AND和OR,特殊的还有NOT,不考虑自定义函数。
predicate pushdown (谓语下推、谓语前推)
有时英语表示为 pushdown filter (下推过滤),是一个来自关系型数据库的术语,最近也广泛被NoSQL所借用。比较详细一个示例解释见Hive https://cwiki.apache.org/confluence/display/Hive/FilterPushdownDev。
Hive的解释:Predicate pushdown is a term borrowed from relational databases even though for Hive it is predicate pushup. The basic idea is to process expressions as early in the plan as possible.
通俗理解,就是在实际数据读取和SQL实际执行之前预先执行条件语句进行预处理和过滤。
## Why we need to understand Sargable
在很多SQL查询场景中,并不是所有的where都能得到优化,如果你的where语句是不可优化的,很可能你动辄就做了一个扫全表的操作。很多入门学习使用MySQL的人因为玩的量比较小,所以一般都没关注这点,等到量上去几百万千万了,才发现字段需要做索引使其可优化。而另一个更需要关注的场景是Hive这类SQL like数据查询引擎。很多这类查询引擎套了层SQL接口,但底层不一定做了针对性优化。比如Hive虽然可以通过StorageHandler来支持不同的存储层(HDFS/HBase/ES等),但是像HBase和ES,一个不小心就是full scan,全部拿回来做mapreduce,在mr中才进行where的过滤。
对于不同的存储数据库来说,Sargable Operators不完全一样,比如HBase支持按前缀过滤的Scan Filter,而ES默认是不支持的;ES支持OR操作的索引查询,HBase的FilterList是AND的关系。因此想去做针对性优化时,熟悉Hive的Operators和数据库能支持的predicate pushdown或索引查询都是不可或缺的。
另外还有的情况是,对于SQL语义一样的两条不同写法的查询,优化支持可能会不一样;有些查询条件看起来可优化但因为存储层支持的原因变得不可优化了。前者有一定工作经验的人都能理解,不然为什么需要做SQL查询优化和管理;后者一定程度上可以说是个坑,尤其对于使用者。对于后者要么给于更清晰的使用和文档指引,要么帮助做一些SQL查询计划的优化。但这样一来的话优化的也有限,而且不通用了(像hive-ql就是通用的)。所以解决方案见仁见智,还是要根据需求场景来决定。
本文只是个引子,在数据仓库的需求越来越大的市场下,这种优化是需要被人重视的。