批计算中的多元索引查询方式可以自定义谓词下推配置。目前只能设置与Long、String类型的列做大小比较的谓词是否下推。
背景信息
谓词下推适用于当多元索引中多字段过滤的中间结果数据量较大,则中间结果的合并较为耗时的场景。此时可以将某些字段的过滤从存储层(表格存储)提到计算层(Spark)处理,提高查询效率。
例如select * from table where a = 10 and b < 999999999;
,如果a = 10返回的结果只有1000条,b < 999999999返回的结果有一亿条,则在存储层将1000条结果与一亿条结果做合并比较耗时,此时把b < 999999999提到计算层,Spark只需要对存储层返回的1000条数据作过滤,大大降低了存储层的压力。
谓词支持
Spark谓词支持情况请参见下表。
Spark | 是否支持 | SQL举例 |
---|---|---|
And | 是 | select * from table where a > 1 and b < 0 |
Or | 是 | select * from table where a > 1 or b < 0 |
Not | 是 | select * from table where a != 1 |
EqualTo | 是 | select * from table where a = 1 |
Not+EqualTo | 是 | select * from table where a != 1 |
IsNull | 是 | select * from table where a is null table表中没有a列的行 |
In | 是 | select * from table where a in {1,2,3} 默认最大限制1024 |
LessThan | 是 | select * from table where a < 10 如果SQL语句中使用该谓词的列的类型为Long或者String,则可以通过谓词下推配置设置是否下推,详情见下一节"谓词下推支持说明" |
LessThanOrEqual | 是 | select * from table where a <=10 如果SQL语句中使用该谓词的列的类型为Long或者String,则可以通过谓词下推配置设置是否下推,详情见下一节"谓词下推支持说明" |
GreaterThan | 是 | select * from table where a > 10 如果SQL语句中使用该谓词的列的类型为Long或者String,则可以通过谓词下推配置设置是否下推,详情见下一节"谓词下推支持说明" |
GreaterThanOrEqual | 是 | select * from table where a >= 10 如果SQL语句中使用该谓词的列的类型为Long或者String,则可以通过谓词下推配置设置是否下推,详情见下一节"谓词下推支持说明" |
StringStartsWith | 是 | select * from table where a like "tablestore%" table表中a列以tablestore为prefix的行全部返回 |
地理坐标(String Json)中心距离 | 是 | select * from table where val_geo = '{"centerPoint":"3,0", "distanceInMeter": 100000}' 圆心半径决定的地理圆圈 |
地理坐标(String Json)矩形框 | 是 | select * from table where geo = '{"topLeft":"8,0", "bottomRight": "0,10"}' 左上角,右下角决定的地理矩形 |
地理坐标(String Json)多边形框 | 是 | select * from table where geo = '{"points":["5,0", "5,1", "6,1", "6,10"]}' 多个点组成的地理多边形 |
谓词下推配置
谓词下推配置的参数需要在创建Spark外表时配置。谓词下推规则如下:
- 当过滤条件中的逻辑谓词只存在AND和NOT时,可以自定义谓词是否下推。
- 当过滤条件中的逻辑谓词存在OR时,谓词全部下推,自定义的谓词下推配置(例如E-MapReduce SQL方式的参数配置push.down.range.long=false和push.down.range.string=false)不会生效。
不同的逻辑谓词和下推配置组合使用时,SQL语句举例及预期效果请参见下表。
逻辑谓词 | 下推配置 | SQL举例 | 预期效果 |
---|---|---|---|
全为AND | push.down.range.long=true push.down.range.string=true | select * from table where val_long1 > 1000 and val_long1 is null and name like 'table%' and pk in {12341,213432} | SQL正常 |
全为AND | push.down.range.long=false | select * from table where val_long1 > 1 and name like 'table%' | 与Long类型做大小比较的谓词(LessThan LessThanOrEqual GreaterThan GreaterThanOrEqual)都不会被下推,该谓词交由Spark层来做过滤 spark层获取到的是name like 'table%'的数据,val_long1 > 1交由spark过滤 |
全为AND | push.down.range.string=false | select * from table where val_string1 > 'string1' and name like 'table%' | 与String类型做大小比较的谓词(LessThan LessThanOrEqual GreaterThan GreaterThanOrEqual)都不会被下推,该谓词交由Spark层来做过滤 spark层获取到的是name like 'table%'的数据,val_string1 > 'string1'交由spark过滤 |
全为AND | 存在地理列 | select * from table where val_geo = '{"centerPoint":"3,0", "distanceInMeter": 100000}' and val_long1 = 37691900 and val_long2 > 2134234 | SQL正常val_long2 > 2134234能否被过滤则取决于push.down.range.long的配置 |
存在OR | long,string都配置为可以下推push.down.range.long=true push.down.range.string=true | select * from table where val_long1 > 1000 or val_long1 is null or name like 'table%' and pk in {12341,213432} | SQL正常 |
存在OR | 存在地理列 | select * from table where val_geo = '{"centerPoint":"3,0", "distanceInMeter": 100000}' or val_long1 = 37691900 | SQL正常 |
存在OR | push.down.range.long=false 且SQL语句中存在rangeLong 的过滤字段 | select * from table where val_long1 > 1 and name like 'table%' | 此时push.down.range.long=false不生效,SQL谓词全部下推 |
存在OR | push.down.range.string=false 且SQL语句中存在rangeString 的过滤字段 | select * from table where val_string1 > 'string1' and name like 'table%' | 此时push.down.range.string=false不生效,SQL谓词全部下推 |