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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP