Postgres优化了SELECT和索引

时间:2018-04-26 21:43:53

标签: postgresql select optimization indexing

我写了一个查询来总结金融交易,这样我就可以回到任何日期并找出当时的财务状况。

数据是多公司,因此数据包含所有集团公司的信息

作为财务信息,一些账户在每年结束时自行重置,而其他账户则有余额。

表的结构是:

nominal_account - 为每个帐户返回1行

nominal-transaction_lines - 完整数据集

nominal_period_year - 是基于名义账户,月/年和金融公司的交易摘要。

我的SQL下面有效,但生成需要一分钟(下面的SQL基于今天的日期)。

查询分为几个部分。

案件的第一部分(na1.id = 178)是一个特殊账户,是该财政年度所有收入/支出记录的摘要。

第二部分首先查找摘要表中的任何记录,直到上个月结束,然后转到事务表以查找自当月开始以来的任何记录。加在一起使得平衡。

目前,交易表有大约25万条记录和摘要表26000。

我不是要求为我编写查询,只是提示如何加快查询速度。因此,如果有人可以提出优化方法或哪些索引有助于加快速度,我将非常感激。

SELECT id, nominal_code AS nom_code, description AS descr, COALESCE(management_type,0) AS type,
    case 
        when na1.id = 178
        then    (SELECT coalesce( (SELECT sum(period_movement) 
                                FROM nominal_period_year JOIN nominal_account on nominal_account.id = nominal_period_year.nominal_account
                                WHERE   (period_key/10000000000) <= 201704 AND
                                financial_company = 1 AND
                                nominal_account.profit_or_balance = true)
                                +
                                (SELECT sum(period_movement) FROM nominal_period_year WHERE nominal_account = na1.id AND                
                                (period_key/10000000000) <= 201803 AND nominal_period_year.financial_company = 1)
                                +
                                (SELECT GREATEST(0, sum(db_Amount)) - GREATEST(0, sum(cr_Amount))
                                FROM nominal_transaction_lines
                                WHERE transaction_date between '2018-04-01' AND '2018-04-27'
                                AND original_id = 0
                                AND reversed_by = 0
                                AND status = 'A'
                                AND financial_company = 1 AND status = 'A' AND nominal_account = na1.id)
                                ,0.00) AS balance)
                    ELSE

                        (SELECT coalesce(
                            (SELECT sum(period_movement) FROM nominal_period_year WHERE nominal_account = na1.id AND
                            (case
                                when na1.profit_or_balance = true 
                                    then (period_key/10000000000) > 201704
                                ELSE period_key > 0
                            end)

                            AND (period_key/10000000000) <= 201803 AND nominal_period_year.financial_company = 1)

                            +

                            (SELECT GREATEST(0, sum(db_Amount)) - GREATEST(0, sum(cr_Amount))
                            FROM nominal_transaction_lines
                            WHERE transaction_date between '2018-04-01' AND '2018-04-27'
                            AND original_id = 0
                            AND reversed_by = 0
                            AND financial_company = 1 
                            AND status = 'A' 
                            AND nominal_account = na1.id)
                            ,0) AS balance)
                    end
                    FROM nominal_account AS na1
                        order by nom_code;

0 个答案:

没有答案