postgresql - 使用多个 IN 优化查询
问题描述
我有一个这样的查询:
SELECT * FROM table
WHERE department='param1' AND type='param2' AND product='param3'
AND product_code IN (10-30 alphanumerics) AND unit_code IN (10+ numerics)
AND first_name || last_name IN (10-20 names)
AND sale_id LIKE ANY(list of regex string)
运行时间太高了,所以我被要求优化它。
参数列表因不同用户的代码列而异。每个用户提供他们的代码列表,然后循环访问产品。product 曾经也是一个 IN 子句列表,但它被拆分了。
我尝试过的事情
通过在(部门、类型和产品)上添加索引,我能够获得 4 倍的改进。当前运行时间是 product 的一些值只需要 2-3 秒,而另一些需要 30s。
尝试创建一个预先连接的 first_name || 列 last_name,但运行时改进太小,不值得。
有什么方法可以提高其他子句的性能,例如“IN”子句或 LIKE ANY 子句?
解决方案
根据我替换大型 IN 列表的经验,使用 JOIN 到 VALUES 子句通常可以提高性能。
所以而不是:
SELECT *
FROM table
WHERE department='param1'
AND type='param2'
AND product='param3'
AND product_code IN (10-30 alphanumerics)
利用:
SELECT *
FROM table t
JOIN ( values (1),(2),(3) ) as x(code) on x.code = t.product_code
WHERE department='param1'
AND type='param2'
AND product='param3'
values ()
但是您必须确保列表中没有任何重复项
连接也是错误的,因为连接的值是不同的,然后单独比较每个值,例如('alexander', 'son') would be treated identical to
('alex','anderson')`
你应该使用:
and (first_name, last_name) in ( ('fname1', 'lname1'), ('fname2', 'lname2'))
这也可以写成一个连接
SELECT *
FROM table t
JOIN ( values (1),(2),(3) ) as x(code) on x.code = t.product_code
JOIN (
values ('fname1', 'lname1'), ('fname2', 'lname2')
) as n(fname, lname) on (n.fname, n.lname) = (t.first_name, t.last_name)
WHERE department='param1'
AND type='param2'
AND product='param3'
推荐阅读
- java - 我缺少哪些元素来确保 mailR 通过数据服务器与 Java 集成顺利运行?
- java - Spring Boot:自定义 AutoConfiguration 类找不到属性
- postgresql - docker-compose 启动时如何创建数据库表并在 postgres DB 中插入数据
- arrays - 从 Flutter 中嵌套映射对象的复杂列表访问变量值
- spring-boot - 使用 Dockerfile 为 Spring Boot jar 指示应用程序属性时没有此类文件
- objective-c - 从 macOS 应用程序以编程方式使用 Spotlight 时,如何搜索网络卷?
- ms-access - MS Access - 更改查询以添加更多列,但运行该查询的宏仍仅导出先前存在的列
- json - 我在表格视图中显示来自 JSON 的图像时遇到问题
- flutter - Flutter - 流错误不持久(使用 bloc 模式)
- javascript - R闪亮的DT悬停显示详细表格