Я пытаюсь понять влияние на производительность выбора данных из представления, где один из столбцов в представлении является функцией других данных в исходной таблице.
Выполняются ли вычисления независимо от того, находится ли вычисляемый столбец в списке выбранных столбцов?
Если бы у меня был стол и вид объявлен так
CREATE TABLE price_data (
ticker text, -- Ticker of the stock
ddate date, -- Date for this price
price float8, -- Closing price on this date
factor float8 -- Factor to convert this price to USD
);
CREATE VIEW prices AS
SELECT ticker,
ddate,
price,
factor,
price * factor as price_usd
FROM price_data
Будет ли это умножение выполняться в запросе, подобном приведенному ниже?
select ticker, ddate, price, factor from prices
Есть ли ссылка, которая гарантирует это так или иначе? Я читал документацию по системе правил в Postgres, но я думаю, что ответ на самом деле лежит на оптимизаторе, поскольку ничто в документации системы правил не указывало, что он не будет выбран.
Я подозреваю, что в приведенном выше случае вычисления не выполняются. Я изменил взгляд на использование деление вместо умножения и вставил 0
на factor
в price_data
. Приведенный выше запрос не дал сбоя, но если запрос был изменен для выбора вычисляемого столбца, измененный запрос не выполнен.
Есть ли способ понять, какие вычисления выполняются, когда select
выполняется? Я думаю, что я ищу что-то вроде, EXPLAIN
но это также говорит мне о вычислениях, которые выполняются.
источник
Ответы:
Как сказал @Laurenz, ваш анализ верен: оптимизатор будет избегать оценки выражений столбцов, которые не влияют на результат запроса (и ваша попытка вызвать ошибку деления на ноль является доказательством этого).
Это зависит от того, какие столбцы вы выбираете, но также зависит от категории волатильности выражений столбцов. Оптимизатор может свободно опускать
immutable
и вызыватьstable
функции, если их выходные данные никогда не используются, поскольку они не могут повлиять на результат, ноvolatile
функции могут иметь побочные эффекты, поэтому их не так легко оптимизировать.Например:
Если
volatile
выбран только столбец:... тогда, как вы можете видеть,
stable_function()
отсутствует наexplain
выходе, и отсутствиеNOTICE
подтверждения подтверждает, что этот вызов был оптимизирован.Однако, если
stable
вместо этого выбран столбец:... тогда мы видим, как оба выражения столбца появляются в плане, и
NOTICE
s показывают, что обе функции были выполнены.Похоже, в документах нет явного упоминания об этом поведении, поэтому нет никаких твердых гарантий относительно того, будет ли выражение оцениваться, и вы не должны полагаться на какие-либо побочные эффекты, которые могут иметь ваши вызовы функций.
Но если ваша единственная забота - это производительность, то, пока вы помечаете свои функции как
stable
илиimmutable
где это уместно, вы можете быть достаточно уверены (особенно в таких простых случаях, как этот), что они не будут оцениваться, если они не нужны.(И пока вы там проверяете свои декларации волатильности, вы можете также установить параллельные флаги безопасности .)
источник
Ваше подозрение верно, и вычисление не должно выполняться, если столбец не используется.
Чтобы подтвердить это, посмотрите на вывод
EXPLAIN (VERBOSE)
запроса, который покажет вам возвращенные столбцы.источник