У меня есть следующие функции, которые я хотел бы использовать в запросе SQL (Postgres 9.3):неудачного выступления на СУЩЕСТВУЕТ-положение в функциях
SELECT * FROM test_table tt WHERE has_access(tt.id, tt.login)
CREATE OR REPLACE FUNCTION has_access(integer, integer)
RETURNS boolean AS
$BODY$
SELECT
EXISTS (SELECT true
FROM test_read_access
WHERE id = $1 and login = $2
)
AND
NOT EXISTS (SELECT true
FROM test_no_read_access
WHERE id = $1 and login = $2
)
$BODY$
Это прекрасно работает до тех пор, как я относиться только о функциональной корректности. Поскольку анализатор запросов сообщает мне, что функция должна быть оценена для каждой строки, и поэтому предложения EXISTS не могут быть оптимизированы, как ожидалось. Действительно, вопрос очень медленно по сравнению со следующим запросом (встраивание в СУЩЕСТВУЕТ-пункты без Select-п):
SELECT * FROM test_table tt WHERE
EXISTS (SELECT true
FROM test_read_access
WHERE id = tt.id and login = tt.login
)
AND
NOT EXISTS (SELECT true
FROM test_no_read_access
WHERE id = tt.id and login = tt.login
)
Намерение функции has_access (ID, логин), чтобы сгруппировать некоторые правила доступа в и использовать его в разных запросах. Я имею в виду, что можно сделать что-то вроде этого, чтобы получить хорошую производительность:
SELECT * FROM test_table tt WHERE EXISTS (select has_access(tt.id, tt.login))
CREATE OR REPLACE FUNCTION has_access(integer, integer)
RETURNS SETOF boolean AS
$BODY$
SELECT true
FROM test_read_access
WHERE id = $1 and login = $2
$BODY$
Но теперь у меня есть только один вспомогательный запрос на одной таблицы в функции, и это не является полезным в моем случае. Любое предложение о том, как сделать это правильно, чтобы не столкнуться с проблемами производительности?
Спасибо!
СУЩЕСТВУЕТ имеет тенденцию приводить к коррелированных подзапросов, которые труднее СУБД для оптимизации; использование IN/NOT IN имеет тенденцию быть более эффективным. – okaram
@okaram: совершенно неправильно. Обратите внимание, что в этом случае нет коррелированного подзапроса, так как основного запроса нет. – wildplasser
@wildplasser, запрос в функции не коррелирован, но один выше (но я не понял, что проблема была функцией, когда я сделал комментарий :) – okaram