10-кратное время запроса на PG 12, чем 10 - PullRequest
2 голосов
/ 04 апреля 2020

Итак, у меня есть БД на Aurora r5.2xl, и я создал дубликат БД на i3.2xl (тонны IOPS). Этот новый запрос по какой-то причине занимает в 10 раз больше времени на новом сервере, чем на Aurora, хотя все переменные установлены одинаково.

Примечания:

  • Я уверен, что 100x из-за того, что IOP не является проблемой, это не
  • все настройки и переменные одинаковы
  • Процессор сгорает на 100%, если я поднимаю предел на новом сервере, тогда как на Авроре это не ' отметьте все, так как запрос выполняется так быстро
  • все индексы идентичны, и я даже пытался переиндексировать
  • данные идентичны (один БД имеет несколько дополнительных строк, но это все)
  • пробовал анализ вакуума для обеих таблиц
  • Я сделал pg_dump и pg_restore для баз данных
  • почти все другие запросы выполняются быстрее на новом сервере, кроме этого
  • да, здесь используется ограничение без порядка, но только потому, что если я не ограничу его до 10, потребуется 1 час + до фини sh, прежде чем я смогу опубликовать полярные сияния за 12 секунд до фини sh и psql 12, взяв 1 час +. это более эффективно и НЕ является частью проблемы

Вот запрос

explain analyze SELECT a.id,
          count(b.id) as hotel_count,
          array_agg(b.id) as hotel_ids
   FROM autocomplete a,
        hotel b
   WHERE a.type = 'city'
     AND st_covers(a.poly, b.coords)
     AND st_distance(a.coords, b.coords) < 40000
     AND b.last_seen IS NOT NULL
     AND b.enabled = true
   GROUP BY a.id
   limit 10;

Вот результаты Аврора

Limit  (cost=0.83..1100.64 rows=10 width=56) (actual time=0.522..2.534 rows=10 loops=1)
  ->  GroupAggregate  (cost=0.83..3696781.84 rows=33613 width=56) (actual time=0.521..2.531 rows=10 loops=1)
        Group Key: a.id
        ->  Nested Loop  (cost=0.83..3668393.17 rows=3729135 width=32) (actual time=0.357..2.506 rows=69 loops=1)
"              ->  Index Scan using ""PK_5523204bb8469c2025bcb0b55bc"" on autocomplete a  (cost=0.42..188879.01 rows=33613 width=176) (actual time=0.025..0.280 rows=14 loops=1)"
"                    Filter: (type = 'city'::autocomplete_type_enum)"
                    Rows Removed by Filter: 133
              ->  Index Scan using hotel_coords_idx on hotel b  (cost=0.41..103.49 rows=3 width=48) (actual time=0.109..0.158 rows=5 loops=14)
                    Index Cond: (a.poly && coords)
"                    Filter: ((last_seen IS NOT NULL) AND enabled AND _st_covers(a.poly, coords) AND (_st_distance(a.coords, coords, '0'::double precision, true) < '40000'::double precision))"
                    Rows Removed by Filter: 7
Planning time: 26.210 ms
Execution time: 2.590 ms

А вот новый результаты сервера (нет iowait, но процессор все время горит на 100%, если я установил лимит выше)

Limit  (cost=5215.44..28517.08 rows=10 width=56) (actual time=124.928..484.664 rows=10 loops=1)
  ->  GroupAggregate  (cost=5215.44..80034722.29 rows=34345 width=56) (actual time=124.926..484.643 rows=10 loops=1)
        Group Key: a.id
        ->  Gather Merge  (cost=5215.44..80000159.03 rows=4551193 width=32) (actual time=89.883..559.222 rows=69 loops=1)
              Workers Planned: 2
              Workers Launched: 2
              ->  Nested Loop  (cost=4215.41..79473838.41 rows=1896330 width=32) (actual time=38.777..468.633 rows=162 loops=3)
"                    ->  Parallel Index Scan using ""PK_5523204bb8469c2025bcb0b55bc"" on autocomplete a  (cost=0.42..92511.37 rows=14310 width=176) (actual time=0.017..0.159 rows=12 loops=3)"
"                          Filter: (type = 'city'::autocomplete_type_enum)"
                          Rows Removed by Filter: 84
                    ->  Bitmap Heap Scan on hotel b  (cost=4214.99..5547.18 rows=8 width=48) (actual time=37.861..37.959 rows=13 loops=37)
                          Recheck Cond: (last_seen IS NOT NULL)
                          Rows Removed by Index Recheck: 11
"                          Filter: (enabled AND st_covers(a.poly, coords) AND (st_distance(a.coords, coords, true) < '40000'::double precision))"
                          Rows Removed by Filter: 1
                          Heap Blocks: exact=107
                          ->  BitmapAnd  (cost=4214.99..4214.99 rows=26 width=0) (actual time=37.759..37.759 rows=0 loops=37)
                                ->  Bitmap Index Scan on hotel_coords_idx  (cost=0.00..2.60 rows=117 width=0) (actual time=0.910..0.910 rows=59 loops=37)
                                      Index Cond: (coords && a.poly)
                                ->  Bitmap Index Scan on hotel_last_seen_idx  (cost=0.00..4149.68 rows=258652 width=0) (actual time=36.268..36.268 rows=262908 loops=37)
Planning Time: 1.815 ms
Execution Time: 559.530 ms

Есть идеи, почему это так? Я в недоумении. Новый сервер на самом деле опережает полярное сияние по множеству запросов, включая такой запрос, как «объяснить, проанализировать, выбрать имя из отеля, где last_seen не равно нулю и включен = истинная группа по ограничению имени 1000;» но по какой-то причине этот запрос выполняется намного медленнее

1 Ответ

1 голос
/ 06 апреля 2020

Хорошо, я обнаружил, что PG12 просто плохо оптимизировал этот запрос, что бы я ни пытался. Когда я переписал его как таковой, он работал так же быстро.

WITH x AS
(
SELECT id, poly, coords
FROM autocomplete
WHERE type = 'city'
)
SELECT x.id, 
sum(CASE WHEN last_seen IS NOT NULL THEN 1 ELSE 0 END) AS hotel_count,
array_agg(CASE WHEN last_seen IS NOT NULL THEN b.id ELSE NULL END) AS hotel_ids
FROM x, hotel b
WHERE st_covers(x.poly, b.coords)
     AND st_distance(x.coords, b.coords) < 40000
     AND b.enabled = true
     GROUP BY x.id;

PS12 также делал полное сканирование индекса на last_seen при каждом l oop, в результате чего он go навсегда, так что это было НАМНОГО дешевле удалить last_seen откуда и просто добавить его в условие подсчета по какой-то причине

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...