关于starrocks过滤条件中携带函数,bitmap索引失效

好的,我先看看

@trueeyu咨询下,我通过生成列改写了我的时间字符串函数,那么是否支持在生成列上设置bitmap或者bloomFilter这类的索引呢

Try

mysql> create table t2(c1 int, c2 string, c3 date as str_to_date(c2, “%Y-%m-%d”), index i_c3(c3) using bitmap) primary key(c1) distributed by hash(c1) buckets 1;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t2 values (1, “2024-01-05 01:02:03”), (2, “2024-02-05 02:03:04”);
Query OK, 2 rows affected (0.60 sec)
{‘label’:‘insert_4076c333-6ab3-11ef-a0a3-c688f73e359f’, ‘status’:‘VISIBLE’, ‘txnId’:‘340281’}

mysql> select * from t2 where str_to_date(c2, “%Y-%m-%d”)=“2024-01-06”;
Empty set (0.03 sec)

           - SegmentInit: 1.053ms
             - BitmapIndexFilter: 143.259us
             - BitmapIndexFilterRows: 2

其实你这个场景不一定适合BitmapIndex,什么场景适合,可以看下这个: Bitmap索引适用场景和最佳实践

mysql> explain select * from t2 where str_to_date(c2, “%Y-%m-%d”)=“2024-01-06”;
±--------------------------------------+
| Explain String |
±--------------------------------------+
| PLAN FRAGMENT 0 |
| OUTPUT EXPRS:1: c1 | 2: c2 | 3: c3 |
| PARTITION: RANDOM |
| |
| RESULT SINK |
| |
| 0:OlapScanNode |
| TABLE: t2 |
| PREAGGREGATION: ON |
| PREDICATES: 3: c3 = ‘2024-01-06’ |
| partitions=1/1 |
| rollup: t2 |
| tabletRatio=1/1 |
| tabletList=394614 |
| cardinality=1 |
| avgRowSize=27.0 |
±--------------------------------------+
16 rows in set (0.01 sec)

是的,因为我发现无论我的前缀索引还是bitmap索引本质上都很难起到作用,都是相对基于低基数的字段建了索引,但还是试试看,毕竟能在scan上减少一部分数据,后续的聚合,exchange都会有很好的效果提升

有个办法可以让他有效果,就是让你的时间和排序的ID,近似有关联,并且把data_date改成datetime类型。

你的ID估计是UUID这种吗?

比如ID改成自增的,或是ID的前缀是个时间字段,这样后面那个时间字段和前的这个字段有一定的关联性,这样ZonemapINdex就会有效果了

当前字符串是没有ZonemapIndex的,所以最好是建成datetime类型

@trueeyu
select *
from (select * from test01 where pt <= ‘20240901’) t1
where (date_format(str_to_date(t1.data_date, ‘%Y-%m-%d’), ‘%Y-%m-%d %H:%i:%s’) >=
concat(cast(‘2024-08-28’ as varchar), cast(’ 19:39:50’ as varchar))) limit 1

select *
from test01
where (date_format(str_to_date(data_date, ‘%Y-%m-%d’), ‘%Y-%m-%d %H:%i:%s’) >=
concat(cast(‘2024-08-28’ as varchar), cast(’ 19:39:50’ as varchar)) and pt <= ‘20240901’) limit 1

生成列在字段上添加了别名就失效了

没看到加了别名啊

两个不同的explain
生成列表达式为:

你的意思是表有别名?

@trueeyu 两个explain的predict不一样,一个还是采用函数,一个是采用newCol1

是的,但其实都是对同一张表做了过滤,只是嵌套了下子查询生成表t1.然后用t1.column的方式在做了一层过滤

估计是子查询的问题,导致优化器没区分出来,你试试子查询里指定上对应的列试试

或是用cte with试试