以下是一个包含CASE表达式语法的简单SQL语句:
SELECT *
FROM employee
WHERE
CASE
WHEN emp_salary< 1000
THEN ‘low’
WHEN emp_salary>100000
THEN ‘high’
END = :a
以下是该SQL语句的查询计划(当绑定变量:a等于’low’时,执行时间为1.01秒)。由于CASE表达式无法利用emp_salary索引,查询需要对EMPLOYEE表进行全表扫描。
我们可以通过使用多个OR条件将CASE表达式重构为以下语法:
select *
from employee
where (emp_salary < 1000 and
‘low’ = :a or
((not (emp_salary < 1000)) or
emp_salary is null) and
emp_salary > 100000 and
‘high’ = :a)
通过将多个OR条件与AND操作(例如’low’ = :a)结合,可以有效禁用对EMPLOYEE表的不必要数据搜索。
以下是重构后SQL的查询计划(执行速度提升至0.005秒),性能比原始语法快约200倍。新的查询计划显示使用了emp_salary索引的位图索引扫描(Bitmap Index Scan)。
这类SQL重写可以通过Tosska SQL Tuning Expert for PostgreSQL自动完成。实际上,还存在其他性能更优的改写方法,但由于篇幅限制无法在此详述,后续可能会在我的博客中进一步探讨。
Tosska SQL Tuning Expert Pro for PostgreSQL – Tosska Technologies Limited