内容提要
最近在Postgres Slack上遇到了一个有趣的性能问题,涉及到一个SQL查询,该查询将两个表连接起来,并在其中一个表上应用了一个ANY过滤器。问题的SQL类似于以下内容:SELECT tbl1.col1 FROM tbl1 INNER JOIN tbl2 ON tbl1.col1 = tbl2.col1 WHERE tbl2.col1 IN (1,2,3)。问题的执行计划显示,过滤器没有被推送到tbl1表的访问路径上,尽管它与应用过滤器的相同列进行了连接。通过对不同条件的相同SQL进行测试,发现过滤器在等式过滤和IN过滤时都能被推送到两个表上。解决方案是手动在连接中的每个表的列上应用过滤器。希望Postgres能够自动推送应用于连接列的谓词或过滤器。
关键要点
-
在Postgres Slack上遇到一个SQL查询性能问题,涉及两个表的连接和ANY过滤器。
-
问题SQL示例:SELECT tbl1.col1 FROM tbl1 INNER JOIN tbl2 ON tbl1.col1 = tbl2.col1 WHERE tbl2.col1 IN (1,2,3)。
-
执行计划显示,过滤器没有被推送到tbl1的访问路径上,尽管它与连接的列相同。
-
测试发现,等式过滤和IN过滤时,过滤器可以被推送到两个表上。
-
解决方案是手动在连接的每个表的列上应用过滤器。
-
重写SQL以手动应用过滤器:SELECT tbl1.col1 FROM tbl1 INNER JOIN tbl2 ON tbl1.col1 = tbl2.col1 WHERE tbl2.col1 = ANY (ARRAY[1,2,3]) AND tbl1.col1 = ANY (ARRAY[1,2,3]);
-
希望Postgres能够自动推送应用于连接列的谓词或过滤器。