Выборка PostgreSQL (иногда) слишком медленная - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть таблица с несколькими миллионами строк, в которую я постоянно вставляю новые данные, а также извлекаю.

Структура:

                ('orig_city', 'INTEGER NOT NULL'),
                ('dest_city', 'INTEGER NOT NULL'),
                ('dep_date', 'DATE NOT NULL'),
                ('orig_city_code', 'TEXT NOT NULL'),
                ('dest_city_code', 'TEXT NOT NULL'),
                ('trip_id', 'TEXT'),
                ('agent', 'TEXT'),
                ('source', 'TEXT'),
                ('price', 'INTEGER'),
                ('deep_link', 'TEXT'),
                ('ts', 'TIMESTAMP(0) WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP'),
                ('PRIMARY KEY', '(trip_id, agent, source)')

с idx_trips_201809 = 'orig_city, dest_city, dep_date'

Обычно он работает достаточно хорошо, но я понял, что время от времени появляются SELECT запросы, которые слишком медленные.

Я видел, что пару раз это заняло даже больше 40 секунд. К сожалению, я не смог скопировать их для команды EXPLAIN.

Все команды выполняются через python. Вот пример.

Запрос:

sql_query = """SELECT * FROM trips_201809 WHERE (orig_city = %s OR dest_city = %s) AND dep_date = %s"""
vals = (91, 279, 2018-09-21)

cur.execute(sql_query, vals)
fetched = cur.fetchall()

, где 2018-09-21 - это datetime.date объект.

EXPLAIN ANALYZE показывает:

('Bitmap Heap Scan on trips_201809  (cost=45576.77..50231.46 rows=2430 width=769) (actual time=1055.970..5993.580 rows=2597 loops=1)',)
("  Recheck Cond: (((orig_city = 91) AND (dep_date = '2018-09-21'::date)) OR ((dest_city = 279) AND (dep_date = '2018-09-21'::date)))",)
('  Heap Blocks: exact=1199',)
('  ->  BitmapOr  (cost=45576.77..45576.77 rows=2438 width=0) (actual time=1038.635..1038.635 rows=0 loops=1)',)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..593.63 rows=1824 width=0) (actual time=22.119..22.119 rows=1605 loops=1)',)
("              Index Cond: ((orig_city = 91) AND (dep_date = '2018-09-21'::date))",)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..44982.90 rows=614 width=0) (actual time=1016.514..1016.514 rows=1004 loops=1)',)
("              Index Cond: ((dest_city = 279) AND (dep_date = '2018-09-21'::date))",)
('Planning time: 0.927 ms',)
('Execution time: 5994.242 ms',)

-

('Bitmap Heap Scan on trips_201809  (cost=45576.77..50231.46 rows=2430 width=769) (actual time=2923.961..2984.264 rows=2597 loops=1)',)
("  Recheck Cond: (((orig_city = 91) AND (dep_date = '2018-09-21'::date)) OR ((dest_city = 279) AND (dep_date = '2018-09-21'::date)))",)
('  Heap Blocks: exact=1199',)
('  ->  BitmapOr  (cost=45576.77..45576.77 rows=2438 width=0) (actual time=2923.785..2923.785 rows=0 loops=1)',)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..593.63 rows=1824 width=0) (actual time=1.818..1.818 rows=1605 loops=1)',)
("              Index Cond: ((orig_city = 91) AND (dep_date = '2018-09-21'::date))",)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..44982.90 rows=614 width=0) (actual time=2921.966..2921.966 rows=1004 loops=1)',)
("              Index Cond: ((dest_city = 279) AND (dep_date = '2018-09-21'::date))",)
('Planning time: 0.731 ms',)
('Execution time: 2984.482 ms',)

-

('Bitmap Heap Scan on trips_201809  (cost=45576.77..50231.46 rows=2430 width=769) (actual time=231.375..233.616 rows=2598 loops=1)',)
("  Recheck Cond: (((orig_city = 91) AND (dep_date = '2018-09-21'::date)) OR ((dest_city = 279) AND (dep_date = '2018-09-21'::date)))",)
('  Heap Blocks: exact=1200',)
('  ->  BitmapOr  (cost=45576.77..45576.77 rows=2438 width=0) (actual time=231.222..231.222 rows=0 loops=1)',)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..593.63 rows=1824 width=0) (actual time=1.781..1.781 rows=1605 loops=1)',)
("              Index Cond: ((orig_city = 91) AND (dep_date = '2018-09-21'::date))",)
('        ->  Bitmap Index Scan on idx_trips_201809  (cost=0.00..44982.90 rows=614 width=0) (actual time=229.440..229.440 rows=1005 loops=1)',)
("              Index Cond: ((dest_city = 279) AND (dep_date = '2018-09-21'::date))",)
('Planning time: 0.665 ms',)
('Execution time: 233.778 ms',)

Я вижу, что проблема в исполнении, а не в планировании. Но я не могу выяснить, что именно делает его медленным.

Почему времена выполнения такие переменные?

И как я мог избежать этого иногда так долго?


Дополнительная информация по запросу в комментариях.

Селективность для типичного запроса:

  • dep_date: 3%
  • orig_city: от 0,1 до 1%
  • dest_city: от 0,1 до 1%

Указатель, упомянутый в планах, - это тот, который я объяснил в начале вопроса. Я отредактировал это, чтобы сделать его более понятным

В этой таблице, которая на данный момент является критической, около 3% строк будет выбрано на определенную дату. Тем не менее, у меня есть другие подобные таблицы, где этот% будет также между 0,1 - 1%.


Редактировать

Добавление индекса dep_date, orig_city, dest_city улучшило скорость выборки. Тем не менее, это все еще не так быстро, как я ожидал. Любые дополнительные предложения приветствуются.

('Bitmap Heap Scan on trips_201809  (cost=1326.19..13315.79 rows=6432 width=772) (actual time=553.464..1273.092 rows=6577 loops=1)',)
("  Recheck Cond: (((dep_date = '2018-09-21'::date) AND (orig_city = 353)) OR ((dep_date = '2018-09-21'::date) AND (dest_city = 106)))",)
('  Heap Blocks: exact=2010',)
('  ->  BitmapOr  (actual time=552.436..552.436 rows=0 loops=1)',)
('        ->  Bitmap Index Scan on idx_trp_201809  (cost=0.00..27.56 rows=2739 width=0) (actual time=0.300..0.300 rows=2136 loops=1)',)
("              Index Cond: ((dep_date = '2018-09-21'::date) AND (orig_city = 353))",)
('        ->  Bitmap Index Scan on idx_trp_201809  (cost=0.00..1297.99 rows=3771 width=0) (actual time=552.134..552.134 rows=4926 loops=1)',)
("              Index Cond: ((dep_date = '2018-09-21'::date) AND (dest_city = 106))",)
('Planning time: 100.031 ms',)
('Execution time: 1273.483 ms',)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...