【标题描述】:
【测试类型:SQL功能/存储功能/接口功能/工具功能/性能/并发/压力长稳/故障注入/安全/资料/编码规范】【测试版本:3.1.0】 问题描述
带有or过滤条件的连接查询没有进行下推,大数据量时影响性能。
【操作系统和硬件信息】(查询命令: cat /etc/system-release, uname -a):
【测试环境】(单机/1主x备x级联备):
单机
【被测功能】:
【测试类型】:
【数据库版本】(查询命令: gaussdb –V):
【预置条件】:
create table k1(id int,id1 int);
create table k2(id int,id1 int);
【操作步骤】(请填写详细的操作步骤):
explain select * from k1,k2 where (k1.id=1 and k2.id=2) or (k1.id=2 and k2.id=1);
【预期输出】:
pg12输出如下:
Nested Loop (cost=0.00..94.44 rows=1 width=16)
Join Filter: (((k1.id = 1) AND (k2.id = 2)) OR ((k1.id = 2) AND (k2.id = 1)))
-> Seq Scan on k1 (cost=0.00..42.23 rows=21 width=8)
Filter: ((id = 1) OR (id = 2))
-> Materialize (cost=0.00..42.34 rows=21 width=8)
-> Seq Scan on k2 (cost=0.00..42.23 rows=21 width=8)
Filter: ((id = 2) OR (id = 1))
【实际输出】:
Nested Loop (cost=0.00..103977.88 rows=231 width=16)
Join Filter: (((k1.id = 1) AND (k2.id = 2)) OR ((k1.id = 2) AND (k2.id = 1)))
-> Seq Scan on k1 (cost=0.00..31.49 rows=2149 width=8)
-> Materialize (cost=0.00..42.23 rows=2149 width=8)
-> Seq Scan on k2 (cost=0.00..31.49 rows=2149 width=8)
【原因分析】:
缺少extract_restriction_or_clauses优化
【日志信息】(请附上日志文件、截图、coredump信息):
【测试代码】:
Hey @sunshine_22, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at Here to find the details.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
Hi @sunshine_22, please use the command /sig xxx to add a SIG label to this issue.
For example: /sig sqlengine or /sig storageengine or /sig om or /sig ai and so on.
You can find more SIG labels from Here.
If you have no idea about that, please contact with @xiangxinyong , @zhangxubo .
您好,关于这个优化点,曾出现过一个问题,or的短路作用会失效,最终结果将代码回退了。
参考: https://e.gitee.com/opengaussorg/dashboard?issue=I38C7H
是不是placeholder导致的,我现在的本地修改是:
if (root->placeholder_list == NIL)
extract_restriction_or_clauses(root);
不是placeholder导致的,例如对于条件 (A1 and B1) or (sqrt(a2)>1 and B2),
由于join条件、数据内容等因素,当or前面不满足时,能保证a2列的值大于0,即:若B1为false,则a2 > 0。而当下推的话,B1无法保证a2 > 0,导致sqrt(a2)报错,入参为负值。
详细用例和分析可参考上面贴的issue里的评论。
当然这个issue内场景确实比较特殊且略带一些诡异和不讲理,其实只要是下推,都可能无法保证条件之间的短路关系,造成类似情况,之前应该只关注单点问题了,最后就回退掉这个优化了。如您对这种OR下推确实有需求的话,可以填报一个SQL sig议题,一起讨论一下。
这样的话,我还是本地加个GUC参数吧,如果遇到上面情况,把优化关掉,或者缺省关闭,需要时打开!
嗯嗯,加个GUC参数确实是最快速简单且有效的方法。
如果可以的话,也欢迎您将优化代码贡献到社区,之前那个问题的年代社区组织还没有很成熟的运作起来,现在可以在 SQL SIG 进行讨论,这个优化点能带来的收益其实还是蛮大的。
那这个如果没有问题的话,issue关掉了?
已验收
登录 后才可以发表评论