TransWikia.com

Производительность запроса на выборку расстояния и времени

Stack Overflow на русском Asked by user386032 on December 9, 2021

Как можно увеличить производительность запроса, на большой выборке (3 млн) это превращается в настоящий кошмар, индексы созданы. Вполне допускаю использование промежуточных таблиц если это как то может помочь производительности.

    select
         case when cast(a.serial as bigint) > cast(b.serial as bigint) then b.serial else a.serial end a_serial,
         case when cast(a.serial as bigint) > cast(b.serial as bigint) then a.serial else b.serial end b_serial,
         a.time a_time, b.time b_time,
         a.messagetype a_mess, b.messagetype b_mess
from serial_tmp as a
   join serial_tmp b
        on abs(DATEDIFF('second', a.time, b.time))<=20
               and st_dwithin(a.points, b.points, 1000)
               and left(a.serial,5) = left(b.serial,5)
               and a.serial!=b.serial
               and a.messagetype = b.messagetype

Индексы:

create index geo_tmp_idx on serial_tmp using gist (points);
create index master_tmp_idx on serial_tmp (serial,time);
create index b_tree_desc_tmp_idx on serial_tmp using btree(time desc );

Ответ планировщика:

QUERY PLAN
Nested Loop  (cost=0.67..30061774579.19 rows=100885378 width=88)
  ->  Seq Scan on serial_tmp a  (cost=0.00..159944.74 rows=3445474 width=59)
  ->  Index Scan using geo_tmp_idx on serial_tmp b  (cost=0.67..8724.22 rows=1 width=59)
        Index Cond: (points && _st_expand(a.points, '1000'::double precision))
        Filter: (((a.serial)::text <> (serial)::text) AND (a.messagetype = messagetype) AND ("left"((a.serial)::text, 5) = "left"((serial)::text, 5)) 
        AND (abs(datediff('second'::character varying, a.time, time)) <= 20) AND st_dwithin(a.points, points, '1000'::double precision, true))

Ответ analyse, buffers

QUERY PLAN
Nested Loop  (cost=86.93..13587.47 rows=8769 width=88) (actual time=1657.261..1657.261 rows=0 loops=1)
  Buffers: shared hit=232870 read=693
  ->  Bitmap Heap Scan on serial_tmp a  (cost=17.43..526.51 rows=130 width=59) (actual time=0.164..0.317 rows=604 loops=1)
        Recheck Cond: ((serial)::text = '12345634656887435'::text)
        Heap Blocks: exact=13
        Buffers: shared hit=12 read=10
        ->  Bitmap Index Scan on master_serial_tmp_idx  (cost=0.00..17.40 rows=130 width=0) (actual time=0.146..0.146 rows=604 loops=1)
              Index Cond: ((serial)::text = '12345634656887435'::text)
              Buffers: shared read=9
  ->  Bitmap Heap Scan on serial_tmp b  (cost=69.50..98.77 rows=1 width=59) (actual time=2.739..2.739 rows=0 loops=604)
        Recheck Cond: ("left"((serial)::text, 5) = "left"((a.serial)::text, 5))
        Filter: (((a.serial)::text <> (serial)::text) AND (a.messagetype = messagetype) AND (abs(datediff('second'::character varying, a.time, time)) <= 20) AND st_dwithin(a.points, points, '1000'::double precision, true))
        Rows Removed by Filter: 598
        Heap Blocks: exact=7824
        Buffers: shared hit=232858 read=683
        ->  BitmapAnd  (cost=69.50..69.50 rows=1 width=0) (actual time=2.577..2.577 rows=0 loops=604)
              Buffers: shared hit=225045 read=669
              ->  Bitmap Index Scan on geo_serial_tmp_idx  (cost=0.00..29.66 rows=154 width=0) (actual time=2.207..2.207 rows=9498 loops=604)
                    Index Cond: (points && _st_expand(a.points, '1000'::double precision))
                    Buffers: shared hit=212381 read=649
              ->  Bitmap Index Scan on pattern_5_serial_tmp  (cost=0.00..39.58 rows=1175 width=0) (actual time=0.288..0.288 rows=3617 loops=604)
                    Index Cond: ("left"((serial)::text, 5) = "left"((a.serial)::text, 5))
                    Buffers: shared hit=12664 read=20
Planning Time: 4.320 ms
Execution Time: 1657.334 ms

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP