Может ли оптимизатор запросов извлечь эффективную константу из предложения WHERE, чтобы избежать повторной оценки?

С C11 мы можем различать массивы и указатели, используя _Generic, но я нашел способ сделать это, если вы укажете тип элемента:

#define ARRAY_SIZE(A, T) \
    _Generic(&(A), \
            T **: (void)0, \
            default: _Generic(&(A)[0], T *: sizeof(A) / sizeof((A)[0])))


int a[2];
printf("%zu\n", ARRAY_SIZE(a, int));

Макрос проверяет: 1) pointer-to-A не является указателем на указатель. 2) pointer-to-elem является указателем на T. Он оценивает (void)0 и статически статирует указатели.

Это неполный ответ, но, возможно, читатель может улучшить его и избавиться от этого параметра!

1
задан Laurenz Albe 17 January 2019 в 07:39
поделиться

1 ответ

Все зависит от some_transform и запроса.

Если эта функция имеет значение IMMUTABLE (гарантированно возвращает тот же результат для тех же аргументов) или STABLE (возвращает тот же результат для того же аргумента в течение текущего запроса и не изменяет базу данных) Вы можете пометить свою функцию так же.

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

Функция IMMUTABLE будет оцениваться при планировании запроса, функция STABLE - один раз во время выполнения.

Это поможет вам с запросом, подобным

WHERE a.x = some_text_predicate('const')

, но не с

WHERE some_text_predicate(a.x) = 'const'

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

Если вы не можете избежать частого вызова функции, вторая функция может быть лучше, потому что функции PL / pgSQL кэшируют планы выполнения. Но вы не можете избежать того, что дорогая функция вызывается таким образом несколько раз.

0
ответ дан Laurenz Albe 17 January 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: