【发布时间】:2017-05-05 10:28:06
【问题描述】:
考虑以下 sql 查询:
SELECT a,b,c
FROM t
WHERE (id1 = :p_id1 OR :p_id1 IS NULL) AND (id2 = :p_id2 OR :p_id2 IS NULL)
Markus Winand 在他的“SQL Performance explained”一书中将这种方法称为所有性能最差的反模式之一,并解释了原因(数据库必须为最坏的情况准备计划当所有过滤器都被禁用时)。
但后来他也写道,对于 PostgreSQL,这个问题只有在重新使用语句 (PreparedStatement) 句柄时才会出现。
现在还假设上面的查询被包装到函数中,例如:
CREATE FUNCTION func(IN p_id1 BIGINT,IN p_id2 BIGINT)
...
$BODY$
BEGIN
...
END;
$BODY$
到目前为止,我对几点有误解:
在函数包装的情况下还会出现这个问题吗? (我试图查看函数调用的执行计划,但即使使用
SET auto_explain.log_nested_statements = ON,Postgres 也不会向我显示内部函数调用的详细信息)。假设我正在处理遗留项目,不能更改函数本身,只能更改 java 执行代码。在这里避免准备好的语句并每次使用动态查询会更好吗? (假设执行时间很长,最多几秒钟)。说这个,大概是丑的做法:
getSession().doWork(connection -> {
ResultSet rs = connection.createStatement().executeQuery("select * from func("+id1+","+id2+")");
...
})
【问题讨论】:
标签: java sql performance postgresql jdbc