如何提高 PostgreSQL 9.5 中的查询性能?

Posted

技术标签:

【中文标题】如何提高 PostgreSQL 9.5 中的查询性能?【英文标题】:How can i increase the performance of query in PostgreSQL 9.5? 【发布时间】:2018-09-20 18:50:31 【问题描述】:

下面提到的查询调用另一个过程getcurrencyexchangerate()。这怎么能调用一次,到处使用呢?如何在 where 子句之外使用 "CASE WHEN in_currency != -1 THEN speedy.currency_code = in_currency ELSE TRUE END" 以提高性能?

SELECT 
    -- LOGINS
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('logins') THEN
        speedy.count ELSE 0 END),0) as login,
    -- REGISTRATIONS
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('registrations') THEN
        speedy.count ELSE 0 END),0) as registration,
    -- COMPLETED DEPOSITS
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('manual_deposit', 'deposit') AND
        LOWER(speedy.status) IN ('success', 'pending approval') THEN
        (speedy.amount_1 * (CASE WHEN in_currency = -1 THEN (SELECT getcurrencyexchangerate(speedy.currency_code)) ELSE 1 END) )
        ELSE 0 END),0) as deposit,
    -- COMPLETED WITHDRAWS
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('withdraw') AND
        LOWER(speedy.status) IN ('success') THEN
        (speedy.amount_2 * (CASE WHEN in_currency = -1 THEN (SELECT getcurrencyexchangerate(speedy.currency_code)) ELSE 1 END) )
        ELSE 0 END),0) as withdraw,
    -- BONUS SUM
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('bonus', 'manual_bonus') AND
        LOWER(speedy.status) IN ('success') THEN
        (speedy.amount_1 * (CASE WHEN in_currency = -1 THEN (SELECT getcurrencyexchangerate(speedy.currency_code)) ELSE 1 END) )
        ELSE 0 END),0) as bonus,
    -- MANUAL BONUS SUM
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('manual_bonus') AND
        LOWER(speedy.status) IN ('success') THEN
        (speedy.amount_1 * (CASE WHEN in_currency = -1 THEN (SELECT getcurrencyexchangerate(speedy.currency_code)) ELSE 1 END) )
        ELSE 0 END),0) as manualbonus,
    -- BONUS WAGERED
    COALESCE(sum( 
        CASE WHEN speedy.base_transaction_type IN ('bonus_wagered') AND
        LOWER(speedy.status) IN ('success') THEN
        (speedy.amount_1 * (CASE WHEN in_currency = -1 THEN (SELECT getcurrencyexchangerate(speedy.currency_code)) ELSE 1 END) )
        ELSE 0 END),0) as bonuswager
FROM speedy_reports_data AS speedy
WHERE 
    speedy.for_date BETWEEN '2017-08-31' AND '2018-08-31' AND
    (CASE WHEN in_currency != -1 THEN speedy.currency_code = in_currency ELSE TRUE END)

speedy_reports_data 表在列(for_date、skin_id、country_code、currency_code、is_test、base_transaction_type、status)上具有相同顺序的复合键。此表上没有其他索引

【问题讨论】:

in_currency 可能的值是多少?你的情况似乎不正确 整数将以货币形式出现,其中每个 id 都映射到一种货币。例如 1-> 美元 2-> 欧元。对于-1值,需要把所有币种的数据汇总起来,换算成单一币种 【参考方案1】:

查看您的查询

为speedy_reports_data表一个复合

index  on columns (for_date, in_currency, currency_code )

【讨论】:

这不是一个覆盖索引(反正我认为没有必要)。它将允许通过索引访问。但是,我不确定索引访问的速度有多快,因为他选择了表的主要部分(一整年)。尽管如此,良好的起点。点赞。 @TheImpaler 。我建议至少并索引 where 中涉及的列。不要涵盖所有请求的列,但应该为 where 子句评估提供帮助。

以上是关于如何提高 PostgreSQL 9.5 中的查询性能?的主要内容,如果未能解决你的问题,请参考以下文章

如何提高此 PostgreSQL 查询在索引扫描中的性能

如何在 docker 上更改 postgreSQL 9.5 的时区?

如何确定 upsert 是不是是 PostgreSQL 9.5+ UPSERT 的更新?

如何在 PostgreSQL 9.5 中为“int”数据类型设置大小限制

如何在 PostgreSQL 9.5 中为“int”数据类型设置大小限制

如何在Ubuntu 16.04和14.04 LTS中安装PostgreSQL 9.5