sql - 如何加快 Postgresql 中复杂查询的速度

标签 sql postgresql postgresql-performance

如何加快以下查询的执行速度?仅检索 37 条记录就花费了 65 秒。大家有什么解决办法吗? (我在 x86_64-unknown-linux-gnu 上使用 PostgreSQL 9.1.6,由 gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) 编译,64 位) 这是查询:

select cc.claim_id, 
cc.claim_date, 
CONCAT(cc.user_id, ' | ', uu.user_name) as user_name,
CONCAT(f_get_channel_id_by_territory_id(cc.territory_id), ' | ', f_get_channel_name(f_get_channel_id_by_territory_id(cc.territory_id))) AS channel_name,
f_get_cluster(cc.user_id) AS cluster_id,
ff.frontliner_name 
from t_trx_card_claim cc join t_mtr_user uu on uu.user_id = cc.user_id
left join t_mtr_outlet_frontliner ff on f_get_territory_id(ff.outlet_id) = cc.territory_id
where f_get_cluster(cc.user_id) = '36'

这是解释分析输出( see also on explain.depesz.com ):

Nested Loop Left Join  (cost=0.00..83503.84 rows=646 width=47) (actual time=2000.830..65689.982 rows=37 loops=1)
  Join Filter: (f_get_territory_id(ff.outlet_id) = cc.territory_id)
  ->  Nested Loop  (cost=0.00..433.50 rows=7 width=35) (actual time=174.417..198.364 rows=37 loops=1)
        ->  Seq Scan on t_trx_card_claim cc  (cost=0.00..375.53 rows=7 width=21) (actual time=174.407..197.932 rows=37 loops=1)
              Filter: (f_get_cluster(user_id) = 36)
        ->  Index Scan using ix_user_8 on t_mtr_user uu  (cost=0.00..8.27 rows=1 width=22) (actual time=0.008..0.009 rows=1 loops=37)
              Index Cond: ((user_id)::text = (cc.user_id)::text)
  ->  Materialize  (cost=0.00..1811.51 rows=42701 width=21) (actual time=0.006..30.225 rows=42701 loops=37)
        ->  Seq Scan on t_mtr_outlet_frontliner ff  (cost=0.00..1347.01 rows=42701 width=21) (actual time=0.003..27.457 rows=42701 loops=1)
Total runtime: 65690.524 ms

最佳答案

重大问题可能出现在函数 f_get_territory_id 和 f_get_cluster 中 - 强烈建议不要在 WHERE 和 FROM(JOIN 谓词)子句中使用函数(如果使用函数索引则异常(exception),因此这些函数必须是不可变的)。

关于sql - 如何加快 Postgresql 中复杂查询的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13487244/

相关文章:

php - 无法将字段记录到数据库中(php、SQL)

sql - 搜索结果按特定顺序显示?

python - 使用具有默认值的列将数据框复制到 postgres 表

sql - 提高查询速度 : simple SELECT in big postgres table

SQL - Friendship 表的最佳实践

php - 如何将 SQLite ROWID 转换为等效的 mysql 查询?

c++ - 如何在 PostgreSQL 中创建插入、删除或更新命令的信号并在 C++ 中处理它们?

node.js - 尽管我使用了正确的凭据,但 Strapi 在生产中给了我数据库错误

postgresql - 表分区与具有许多索引的非分区表

sql - PostgreSQL 查询未使用索引