Функция даты Postgresql сканирует каждую строку в каждом разделе и работает очень медленно - PullRequest
0 голосов
/ 01 июня 2018

У меня большая секционированная таблица tbl_VehicleEntry.Я создал функцию F_GetSysDate() (для совместимости моей функции с оракулом)

CREATE TABLE tbl_vehicleentry (

vehicleentry_code numeric(12,0) NOT NULL,
shift_date timestamp without time zone NOT NULL,
shift_code numeric(1,0) NOT NULL,
booth_code numeric(2,0) NOT NULL,
.
.
N number of columns);

Такие разделы ...

CREATE TABLE tbl_vehicleentry_2016 (

CONSTRAINT tbl_vehicleentry_2016_shift_date_check CHECK (((shift_date >= '2016-01-01'::date) AND (shift_date < '2017-01-01'::date)))

) наследует (tbl_vehicleentry);

ALTER TABL tbl_vehicleentry_2016 ВЛАДЕЛЕЦ К TMS; * 101b * 201

CONSTRAINT tbl_vehicleentry_201701_shift_date_check CHECK (((shift_date >= '2017-01-01'::date) AND (shift_date < '2017-02-01'::date)))

)

INHERITS (tbl_vehicleentry);

ALTER TABLE tbl_vehicleentry_201701 ВЛАДЕЛЕЦ tms;

CREATE TABLE tbl_vehicleentry_201031

)

Унаследовано (tbl_vehicleentry);

ALTER TABLE tbl_vehicleentry_201702 ВЛАДЕЛЬЦЕВ tms;

CREATE TABLE tbl_vehicleentry_201703 (* 10 * * 10 * 10 *) 1041 * 10 10 * 411*

INHERITS (tbl_vehicleentry);

ALTER TABLE tbl_vehicleentry_201703 ВЛАДЕЛЕЦ tms;

..... И так в месячных разделах на 2017 год и далее

-- FUNCTION: public.f_getsysdate()
-- DROP FUNCTION public.f_getsysdate();

CREATE OR REPLACE FUNCTION public.f_getsysdate(
    )
    RETURNS timestamp without time zone
    LANGUAGE 'plpgsql'

    COST 100
    STABLE SECURITY DEFINER 
AS $BODY$

DECLARE
    V_ReturnName   VARCHAR2 ;
BEGIN  
    RETURN current_timestamp::timestamp(0);
END

$BODY$;

ALTER FUNCTION public.f_getsysdate()
    OWNER TO tms;

Теперь, когда я запускаю запрос вроде ...

Explain analyze
SELECT MAX(Vehicleentry_Code) FROM tbl_VehicleEntry
WHERE Shift_Date >= f_getsysdate() - 30 

Или

Explain analyze
SELECT MAX(Vehicleentry_Code) FROM tbl_VehicleEntry
WHERE Shift_Date >= f_getsysdate() - interval '30' day

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

Агрегат (стоимость = 324.08..324.09 строк = 1 ширина = 32) -> Добавить (стоимость = 0.68..323.88 строк = 79 ширина = 16)

    ->  Index Scan using isd_tbl_vehicleentry on tbl_vehicleentry  (cost=0.68..4.70 rows=1 width=8)
          Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))


    ->  Bitmap Heap Scan on tbl_vehicleentry_2015  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))


          ->  Bitmap Index Scan on isd_tbl_vehicleentry_2015  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_2016  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_2016  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201701  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201701  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201702  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201702  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201703  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201703  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201704  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201704  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201705  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201705  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201706  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201706  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201707  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201707  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201708  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201708  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201709  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201709  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201710  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201710  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201711  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201711  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201712  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201712  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201801  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201801  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201802  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201802  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201803  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201803  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201804  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201804  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201805  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201805  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201806  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201806  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201807  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201807  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201808  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201808  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201809  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201809  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201810  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201810  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201811  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201811  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

    ->  Bitmap Heap Scan on tbl_vehicleentry_201812  (cost=4.41..12.28 rows=3 width=16)
          Recheck Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

          ->  Bitmap Index Scan on isd_tbl_vehicleentry_201812  (cost=0.00..4.41 rows=3 width=0)
                Index Cond: (shift_date >= (f_getsysdate() - '30 days'::interval day))

** Смотрите, он просканировал каждую строку каждого раздела в моей таблице postgresql и заставил его работать очень медленно.Что может быть не так?

Проблема точно в работе.

Есть ли альтернатива, чтобы сделать это быстрее?Пожалуйста, помогите. **

1 Ответ

0 голосов
/ 01 июня 2018

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

Сначала следует запросить f_getsysdate()затем создайте оператор SQL из результата и выполните его.Таким образом, предел будет постоянным, и оптимизатор PostgreSQL может его использовать.

PostgreSQL может работать лучше, если функция IMMUTABLE, но, исходя из названия, я предполагаю, что это не вариант.

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