Обсуждение: Re: [pgsql-ru-general] Партицирование и план запросов и индексы
привет!
1) сделай таргет default_statistics_target для аналайза максимальный и смотри, чтобы аналайз запускался часто.
2) у тебя что-то с костами (на рендом рид например) -- pg решает, что indexscan очень дорог и идет битмапом
3) а у битмапа возможен (не факт что он был) речек, так как битовая карта -- lossy и надо опять чекать. добавив воркмема можно избежать фазы речека, но она будет написана в плане. главне тут не речек -- а чтение кучи именно осле чтения индекса
4) ! тебе надо захакать его на indexscan
5) возможно хватит и индекса ( driver_id ) без времени: за час 143 точки , за сутки 2К на драйвера. индекс будет в два раза компактнее, а сортировать сотни точек -- совсем быстро
6) ну и надо смотреть на латенси системы, такие скачки -- не очень хорошо (возможно io не хватает, но править это можно по разному)
Суббота, 3 октября 2015, 16:16 +03:00 от "Dmitry E. Oboukhov" <unera@debian.org>:
Имеется таблица
"points"
(
"id" BIGSERIAL,
"driver" TEXT NOT NULL,
"time" TIMESTAMP WITH TIME ZONE NOT NULL,
"lon" NUMERIC(9,6) NOT NULL,
"lat" NUMERIC(9,6) NOT NULL
)
и ежедневно создается партиция
CREATE TABLE "points_2015_10_01" (
LIKE "points" INCLUDING ALL,
CHECK (
"time" >= '2015-10-01 00:00:00'
AND "time" < '2015-10-02 00:00:00'
)
) INHERITS ("points")
Имеется индекс
BTREE ("driver", "time")
Далее каждый раз когда новая партиция создается этот индекс попадает и
в нее.
Вставку осуществляем только в партиции.
Однако выборку делаем из points.
Допустим надо получить трек водителя:
SELECT
"time", "lon", "lat"
FROM
"points"
WHERE
"driver" = 'driver-id'
AND "time" BETWEEN '2015-10-01 11:12:13' AND '2015-10-01 12:30:35'
ORDER BY
"time"
;
Столкнулся что эти запросы выполняются очень большое время, хотя вроде
все под них подстроено.
смотрю EXPLAIN:
Result (cost=0.00..189.86 rows=48 width=24) (actual time=0.064..0.483 rows=143 loops=1)
-> Append (cost=0.00..189.86 rows=48 width=24) (actual time=0.063..0.470 rows=143 loops=1)
-> Seq Scan on points (cost=0.00..0.00 rows=1 width=36) (actual time=0.000..0.000 rows=0 loops=1)
Filter: (("time" >= '2015-10-03 15:41:48+03'::timestamp with time zone) AND ("time" <= '2015-10-03 16:03:28+03'::timestamp with time zone) AND (driver = '310758'::text))
-> Bitmap Heap Scan on points_2015_10_03 points (cost=5.78..189.86 rows=47 width=24) (actual time=0.063..0.460 rows=143 loops=1)
Recheck Cond: ((driver = '310758'::text) AND ("time" >= '2015-10-03 15:41:48+03'::timestamp with time zone) AND ("time" <= '2015-10-03 16:03:28+03'::timestamp with time zone))
-> Bitmap Index Scan on points_2015_10_03_driver_time_idx (cost=0.00..5.77 rows=47 width=0) (actual time=0.049..0.049 rows=143 loops=1)
Index Cond: ((driver = '310758'::text) AND ("time" >= '2015-10-03 15:41:48+03'::timestamp with time zone) AND ("time" <= '2015-10-03 16:03:28+03'::timestamp with time zone))
Total runtime: 0.533 ms
В логе этот же запрос 3 минуты назад выполнялся за 34 сек.
а на explain - 0.533 ms почему такая разница может быть?
Далее
последние две строки мне понятны: берет из индекса с условием под которое индекс построен.
но мне непонятно почему после этого еще делается
-> Bitmap Heap Scan on points_2015_10_03 points (cost=5.78..189.86 rows=47 width=24) (actual time=0.063..0.460 rows=143 loops=1)
Recheck Cond: ((driver = '310758'::text) AND ("time" >= '2015-10-03 15:41:48+03'::timestamp with time zone) AND ("time" <= '2015-10-03 16:03:28+03'::timestamp with time zone))
и речек кондишен.
Почему так?
если выбирать минуя партицию - напрямую, то Bitmap Heap Scan + Recheck Cond
все равно остаются.
Может кто-то пояснить мне этот EXPLAIN?
--
. ''`. Dmitry E. Oboukhov
: :’ : email: unera@debian.org jabber://UNera@uvw.ru
`. `~’ GPGKey: 1024D / F8E26537 2006-11-21
`- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537