Postgres SQL慢查询聚合

时间:2015-11-08 21:12:17

标签: sql postgresql

我有一个聚合查询,结果很慢,我正在寻找“查询”或“索引”的任何改进。

我索引了我使用的所有字段,也许我错过了某些内容,或者您​​可以建议我执行此查询的任何方式

查询:

 EXPLAIN ANALYZE 


SELECT HE.fs_perm_sec_id,
       HE.TICKER_EXCHANGE,
       HE.proper_name,
       OP.shares_outstanding,

  (SELECT factset_industry_desc
   FROM factset_industry_map AS fim
   WHERE fim.factset_industry_code = HES.industry_code) AS industry,



   // slow aggregation

  (SELECT SUM(OIH.current_holdings)
   FROM own_inst_holdings OIH
   WHERE OIH.fs_perm_sec_id = HE.fs_perm_sec_id) AS inst_holdings


FROM own_prices OP
JOIN h_security_ticker_exchange HE ON OP.fs_perm_sec_id = HE.fs_perm_sec_id
JOIN h_entity_sector HES ON HES.factset_entity_id = HE.factset_entity_id

WHERE HE.ticker_exchange = 'BUD-NYS'

ORDER BY OP.price_date DESC LIMIT 1

这篇文章放慢了查询的速度:

  (SELECT SUM(OIH.current_holdings)
   FROM own_inst_holdings OIH
   WHERE OIH.fs_perm_sec_id = HE.fs_perm_sec_id) AS inst_holdings

EXPLAIN ANALYZE

                 Limit  (cost=360.41..360.41 rows=1 width=100) (actual time=920.592..920.592 rows=1 loops=1)
  ->  Sort  (cost=360.41..360.41 rows=1 width=100) (actual time=920.592..920.592 rows=1 loops=1)
        Sort Key: op.price_date
        Sort Method: top-N heapsort  Memory: 25kB
        ->  Nested Loop  (cost=0.26..360.41 rows=1 width=100) (actual time=867.898..920.493 rows=35 loops=1)
              ->  Nested Loop  (cost=0.17..6.43 rows=1 width=104) (actual time=4.882..4.940 rows=35 loops=1)
                    ->  Index Scan using h_sec_exch_factset_entity_id_idx on h_security_ticker_exchange he  (cost=0.09..4.09 rows=1 width=92) (actual time=3.611..3.612 rows=1 loops=1)
                          Index Cond: ((ticker_exchange)::text = 'BUD-NYS'::text)
                    ->  Index Only Scan using own_prices_multiple_idx_1 on own_prices op  (cost=0.09..2.25 rows=32 width=23) (actual time=1.258..1.301 rows=35 loops=1)
                          Index Cond: (fs_perm_sec_id = (he.fs_perm_sec_id)::text)
                          Heap Fetches: 0
              ->  Index Scan using h_entity_sector_multiple_idx_3 on h_entity_sector hes  (cost=0.09..4.09 rows=1 width=14) (actual time=0.083..0.085 rows=1 loops=35)
                    Index Cond: (factset_entity_id = he.factset_entity_id)
              SubPlan 1
                ->  Seq Scan on factset_industry_map fim  (cost=0.00..2.48 rows=1 width=20) (actual time=0.014..0.031 rows=1 loops=35)
                      Filter: (factset_industry_code = hes.industry_code)
                      Rows Removed by Filter: 137
              SubPlan 2
                ->  Aggregate  (cost=347.40..347.40 rows=1 width=6) (actual time=26.035..26.035 rows=1 loops=35)
                      ->  Bitmap Heap Scan on own_inst_holdings oih  (cost=4.36..347.31 rows=177 width=6) (actual time=0.326..25.658 rows=622 loops=35)
                            Recheck Cond: ((fs_perm_sec_id)::text = (he.fs_perm_sec_id)::text)
                            Heap Blocks: exact=22750
                            ->  Bitmap Index Scan on own_inst_holdings_fs_perm_sec_id_idx  (cost=0.00..4.35 rows=177 width=0) (actual time=0.232..0.232 rows=662 loops=35)
                                  Index Cond: ((fs_perm_sec_id)::text = (he.fs_perm_sec_id)::text)
Planning time: 5.806 ms
Execution time: 920.778 ms

1 个答案:

答案 0 :(得分:1)

对于此查询:

SELECT HE.fs_perm_sec_id, HE.TICKER_EXCHANGE, HE.proper_name, OP.shares_outstanding,
       (SELECT factset_industry_desc
        FROM factset_industry_map AS fim
        WHERE fim.factset_industry_code = HES.industry_code
       ) AS industry,
       (SELECT SUM(OIH.current_holdings)
        FROM own_inst_holdings OIH
        WHERE OIH.fs_perm_sec_id = HE.fs_perm_sec_id
       ) AS inst_holdings
FROM own_prices OP JOIN
     h_security_ticker_exchange HE 
     ON OP.fs_perm_sec_id = HE.fs_perm_sec_id JOIN
     h_entity_sector HES
     ON HES.factset_entity_id = HE.factset_entity_id
WHERE HE.ticker_exchange = 'BUD-NYS'
ORDER BY OP.price_date DESC
LIMIT 1;

您需要以下索引:

h_security_ticker_exchange(ticker_exchange, factset_entity_id, fs_perm_sec_id)
own_prices(fs_perm_sec_id)
h_entity_sector(factset_entity_id)
factset_industry_map(factset_industry_code, factset_industry_desc)
own_inst_holdings(fs_perm_sec_id, current_holdings)