原文英文,约800词,阅读约需3分钟。
📝
内容提要
最近在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能够自动推送应用于连接列的谓词或过滤器。
❓
Q&A
在PostgreSQL中,如何优化连接查询的性能?
可以通过手动在连接的每个表的列上应用过滤器来优化性能。
什么是ANY过滤器,它在SQL查询中有什么作用?
ANY过滤器用于检查某个列的值是否在指定的数组中,常用于简化多个值的比较。
在执行计划中,为什么过滤器没有被推送到tbl1的访问路径上?
因为过滤器应用于tbl2的col1,而tbl1的访问路径未受到影响,尽管它们通过相同的列连接。
如何重写SQL以确保过滤器被正确应用?
可以将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]);
在PostgreSQL中,等式过滤和IN过滤的表现有什么不同?
等式过滤可以被推送到两个表上,而IN过滤在某些情况下可能只应用于一个表。
PostgreSQL是否能够自动推送连接列的过滤器?
目前PostgreSQL无法自动推送连接列的过滤器,用户需要手动应用。
🏷️