Как уменьшить стоимость этого запроса, сохранив при этом результаты запроса? - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть следующий запрос, работающий на БД postgres и sqlserver (используйте top для SQL-сервера). Сортировка значения «change_sequence» приводит к высокой стоимости в моем запросе, есть ли способ уменьшить стоимость, но сохранить те же результаты?

Запрос:

SELECT tablename, 
       CAST(primary_key_values AS VARCHAR), 
       primary_key_fields, 
       CAST(min_sequence AS NUMERIC), 
       _changed_fieldlist, 
       _operation,
       min_sequence
FROM (
  SELECT 'memdep' AS tablename, 
         CONCAT_WS(',',dependant,mem_num) AS primary_key_values, 
         'dependant,mem_num,' AS primary_key_fields, 
         _change_sequence AS min_sequence, 
         ROW_NUMBER() OVER(partition by dependant,mem_num order by _change_sequence) AS rn, 
         _changed_fieldlist, 
         _operation 
  FROM mipbi_ods.memdep
  WHERE mipbi_status = 'NEW'
) main 
WHERE rn = 1 
LIMIT 100

По сутито, что я ищу, это записи из "memdep", где у них есть "mipbi_status" из "NEW" с самой низкой "_change_sequence". Я пытался использовать функцию MIN () вместо ROW_NUMBER, скорость примерно на ту же цену, примерно на 5 больше.

Есть ли способ снизить стоимость / скорость запроса. У меня есть около 400 миллионов записей в этой таблице, если это поможет.

Вот объяснение запроса:

Limit  (cost=3080.03..3080.53 rows=100 width=109) (actual time=17.633..17.648 rows=35 loops=1)
  ->  Unique  (cost=3080.03..3089.04 rows=1793 width=109) (actual time=17.632..17.644 rows=35 loops=1)
        ->  Sort  (cost=3080.03..3084.53 rows=1803 width=109) (actual time=17.631..17.634 rows=36 loops=1)
              Sort Key: (concat_ws(','::text, memdet.mem_num))
              Sort Method: quicksort  Memory: 29kB
              ->  Bitmap Heap Scan on memdet  (cost=54.39..2982.52     rows=1803 width=109) (actual time=16.853..17.542 rows=36 loops=1)
                    Recheck Cond: ((mipbi_status)::text = 'NEW'::text)
                    Heap Blocks: exact=8
                    ->  Bitmap Index Scan on idx_mipbi_status_memdet  (cost=0.00..53.94 rows=1803 width=0) (actual time=10.396..10.396 rows=38 loops=1)
                          Index Cond: ((mipbi_status)::text = 'NEW'::text)
Planning time: 0.201 ms
Execution time: 17.700 ms

Я использую меньшую таблицу, чтобы показать здесь, это неТаблица записей 400 миллионов, но индексы и все будут одинаковыми.

Вот план запроса для большой таблицы:

Limit  (cost=47148422.27..47149122.27 rows=100 width=113) (actual time=2407976.293..2407977.112 rows=100 loops=1)
  Output: main.tablename, ((main.primary_key_values)::character varying), main.primary_key_fields, main.min_sequence, main._changed_fieldlist, main._operation, main.min_sequence
  Buffers: shared hit=6269554 read=12205028 dirtied=1893 written=4566983, temp read=443831 written=1016025
  ->  Subquery Scan on main  (cost=47148422.27..52102269.25 rows=707692 width=113) (actual time=2407976.292..2407977.100 rows=100 loops=1)
        Output: main.tablename, (main.primary_key_values)::character varying, main.primary_key_fields, main.min_sequence, main._changed_fieldlist, main._operation, main.min_sequence
        Filter: (main.rn = 1)
        Buffers: shared hit=6269554 read=12205028 dirtied=1893 written=4566983, temp read=443831 written=1016025
        ->  WindowAgg  (cost=47148422.27..50333038.19 rows=141538485 width=143) (actual time=2407976.288..2407977.080 rows=100 loops=1)
              Output: 'claim', concat_ws(','::text, claim.gen_claimnum), 'gen_claimnum,', claim._change_sequence, row_number() OVER (?), claim._changed_fieldlist, claim._operation, claim.gen_claimnum
              Buffers: shared hit=6269554 read=12205028 dirtied=1893 written=4566983, temp read=443831 written=1016025
              ->  Sort  (cost=47148422.27..47502268.49 rows=141538485 width=39) (actual time=2407976.236..2407976.905 rows=100 loops=1)
                    Output: claim._change_sequence, claim.gen_claimnum, claim._changed_fieldlist, claim._operation
                    Sort Key: claim.gen_claimnum, claim._change_sequence
                    Sort Method: external merge  Disk: 4588144kB
                    Buffers: shared hit=6269554 read=12205028 dirtied=1893 written=4566983, temp read=443831 written=1016025
                    ->  Seq Scan on mipbi_ods.claim  (cost=0.00..20246114.01 rows=141538485 width=39) (actual time=0.028..843181.418 rows=88042077 loops=1)
                          Output: claim._change_sequence, claim.gen_claimnum, claim._changed_fieldlist, claim._operation
                          Filter: ((claim.mipbi_status)::text = 'NEW'::text)
                          Rows Removed by Filter: 356194
                          Buffers: shared hit=6269554 read=12205028 dirtied=1893 written=4566983
Planning time: 8.796 ms
Execution time: 2408702.464 ms
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...