PostgreSQL 9.4 Index的速度非常慢

时间:2016-01-11 19:49:23

标签: postgresql select indexing postgresql-performance

运行PostgreSQL 9.4的盒子是32核心系统,每个核心3.5ghz,带有128GB或ram的镜像Samsung pro 850 SSD驱动器,带有ZFS的FreeBSD。这不是PostgreSQL表现不佳的原因!

forex=# explain (analyze, buffers) select pair_name as name, pair_price as price, ts as date from pair_data where pair_name = 'EURUSD' order by ts desc limit 10;
                                                                       QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=201442.55..201442.57 rows=10 width=22) (actual time=10870.395..10870.430 rows=10 loops=1)
   Buffers: shared hit=40 read=139150 dirtied=119
   ->  Sort  (cost=201442.55..203787.44 rows=937957 width=22) (actual time=10870.390..10870.401 rows=10 loops=1)
         Sort Key: ts
         Sort Method: top-N heapsort  Memory: 25kB
         Buffers: shared hit=40 read=139150 dirtied=119
         ->  Bitmap Heap Scan on pair_data  (cost=9069.17..181173.63 rows=937957 width=22) (actual time=614.976..8903.913 rows=951858 loops=1)
               Recheck Cond: ((pair_name)::text = 'EURUSD'::text)
               Rows Removed by Index Recheck: 13624055
               Heap Blocks: exact=33464 lossy=105456
               Buffers: shared hit=40 read=139150 dirtied=119
               ->  Bitmap Index Scan on pair_data_gin_idx1  (cost=0.00..8834.68 rows=937957 width=0) (actual time=593.701..593.701 rows=951858 loops=1)
                     Index Cond: ((pair_name)::text = 'EURUSD'::text)
                     Buffers: shared hit=40 read=230
 Planning time: 0.387 ms
 Execution time: 10871.419 ms
(16 rows)

使用此选项:

forex=# explain (analyze, buffers) with intervals as ( select start, start + interval '4hr' as end from generate_series('2015-12-01 15:00', '2016-01-19 16:00', interval '4hr') as start ) select distinct intervals.start as date, min(pair_price) over w as low, max(pair_price) over w as high, first_value(pair_price) over w as open, last_value(pair_price) over w as close from intervals join pair_data mb on mb.pair_name = 'EURUSD' and mb.ts >= intervals.start and mb.ts < intervals.end window w as (partition by intervals.start order by mb.ts asc rows between unbounded preceding and unbounded following) order by intervals.start;
                                                                                   QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Unique  (cost=64634864.43..66198331.09 rows=815054 width=23) (actual time=1379732.924..1384602.952 rows=82 loops=1)
   Buffers: shared hit=8 read=139210 dirtied=22, temp read=3332596 written=17050
   CTE intervals
     ->  Function Scan on generate_series start  (cost=0.00..12.50 rows=1000 width=8) (actual time=0.135..1.801 rows=295 loops=1)
   ->  Sort  (cost=64634851.92..64895429.70 rows=104231111 width=23) (actual time=1379732.918..1381724.179 rows=951970 loops=1)
         Sort Key: intervals.start, (min(mb.pair_price) OVER (?)), (max(mb.pair_price) OVER (?)), (first_value(mb.pair_price) OVER (?)), (last_value(mb.pair_price) OVER (?))
         Sort Method: external sort  Disk: 60808kB
         Buffers: shared hit=8 read=139210 dirtied=22, temp read=3332596 written=17050
         ->  WindowAgg  (cost=41474743.35..44341098.90 rows=104231111 width=23) (actual time=1341744.405..1365946.672 rows=951970 loops=1)
               Buffers: shared hit=8 read=139210 dirtied=22, temp read=3324995 written=9449
               ->  Sort  (cost=41474743.35..41735321.12 rows=104231111 width=23) (actual time=1341743.502..1343723.884 rows=951970 loops=1)
                     Sort Key: intervals.start, mb.ts
                     Sort Method: external sort  Disk: 32496kB
                     Buffers: shared hit=8 read=139210 dirtied=22, temp read=1154778 written=7975
                     ->  Nested Loop  (cost=9098.12..21180990.32 rows=104231111 width=23) (actual time=271672.696..1337526.628 rows=951970 loops=1)
                           Join Filter: ((mb.ts >= intervals.start) AND (mb.ts < intervals."end"))
                           Rows Removed by Join Filter: 279879180
                           Buffers: shared hit=8 read=139210 dirtied=22, temp read=1150716 written=3913
                           ->  CTE Scan on intervals  (cost=0.00..20.00 rows=1000 width=16) (actual time=0.142..4.075 rows=295 loops=1)
                           ->  Materialize  (cost=9098.12..190496.52 rows=938080 width=15) (actual time=2.125..1962.153 rows=951970 loops=295)
                                 Buffers: shared hit=8 read=139210 dirtied=22, temp read=1150716 written=3913
                                 ->  Bitmap Heap Scan on pair_data mb  (cost=9098.12..181225.12 rows=938080 width=15) (actual time=622.818..11474.987 rows=951970 loops=1)
                                       Recheck Cond: ((pair_name)::text = 'EURUSD'::text)
                                       Rows Removed by Index Recheck: 13623989
                                       Heap Blocks: exact=33485 lossy=105456
                                       Buffers: shared hit=8 read=139210 dirtied=22
                                       ->  Bitmap Index Scan on pair_data_gin_idx1  (cost=0.00..8863.60 rows=938080 width=0) (actual time=601.158..601.158 rows=951970 loops=1)
                                             Index Cond: ((pair_name)::text = 'EURUSD'::text)
                                             Buffers: shared hit=8 read=269
 Planning time: 0.454 ms
 Execution time: 1384653.385 ms
(31 rows)

或者这个选择:

forex=# select count(*) from pair_data;
  count
----------
 21833886
(1 row)

pair_data表只有:

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ...
    String remoteIpAddress = request.getRemoteAddr();
    ...
}

为什么当它们是索引时,它会进行堆扫描?我不明白查询计划发生了什么?任何人都知道问题可能在哪里?

0 个答案:

没有答案