在多表join场景中,一次join的结果会作为后续join的输入。 在更新统计信息的时间间隔内,当我们更新数据时,统计信息没有及时收集,如果我们在此时间间隔内运行多表join查询,优化器可能会因为没有正确的统计信息而选择一个糟糕的策略。
以如下查询为例:
select t1.* from example_tbl t1
join example_tbl02 t2 on t1.city=t2.city and t1.city="chengdu"
join example_tbl03 t3 on t1.city=t3.city
join example_tbl04 t4 on t1.city=t4.city
join example_tbl05 t5 on t1.city=t5.city;
我们以此查询为例分析在doris2.0.4和doris 2.1.0中的表现
doris 2.0.4版本:
执行计划如下:
在这个case中,example_tbl02、example_tbl04、example_tbl05 各有 3000 万行 city="chengdu" 的数据;example_tbl、example_tbl03 没有任何 city="chengdu" 的数据。 在 doris 触发第一次统计信息收集后,我们分别向 example_tbl 和 example_tbl03 中插入 2 行 city="chengdu" 的数据,并在第二次统计信息收集之前运行查询,因此我们得到了不正确的统计信息并在本次查询中选择了一个较差的计划。
我们可以把这个计划树简化一下:
实际运行时分发数据量如下:
braodcast-01: distribute 2 rows of data
broadcast-02: distribute 2 rows of data
broadcast-03: distribute 120 million (2 * 2 * 30million) rows of data
broadcast-04: ditribute 3600 trillion(2 * 2 * 30 million * 30 million) rows of data
可以看到,broadcast-03 和 broadcast-04 由于不正确的统计信息分发了大量数据,容易导致 OOM。
想通的查询在doris 2.1.0中的执行计划如下:
我们简化一下这个执行计划:
实际运行时分发数据量如下:
braodcast-01: distribute 2 rows of data
broadcast-02: distribute 60 million(2 * 30million) rows of data
broadcast-03: distribute 2 rows of data
broadcast-04: ditribute 3600 trillion(2 * 2 * 30 million * 30 million) rows of data
可以看到,broadcast-02和broadcast-04由于统计信息不正确,分发了大量的数据,容易导致OOM。
鉴于以上问题,我们要对统计信息手机机制做新的优化