Ответ 1
Агрегатная функция bool_and()
Просто, коротко, понятно:
SELECT bool_and(archived)
FROM tbl
WHERE ticket = 1;
истина, если все входные значения верны, иначе ложь
Выражение подзапроса EXISTS
Нравится @Mike при условии.
Быстрее. Но вам нужно дополнительно проверить, существуют ли вообще какие-либо строки с ticket = 1
, или вы получите неправильные результаты для несуществующих тикетов:
SELECT EXISTS (SELECT 1 FROM tbl WHERE ticket=1)
AND NOT
EXISTS (SELECT 1 FROM tbl WHERE ticket=1 AND archived = FALSE);
Индексы
Обе формы могут и будут использовать такой индекс:
CREATE index tbl_ticket_idx ON tbl (ticket);
.. что делает оба быстрее, но запрос EXISTS
быстрее, потому что эта форма может перестать сканировать, как только найдена первая подходящая строка. Почти нет разницы между двумя запросами с несколькими строками на заявку, но существенная разница для многих строк на заявку.
Чтобы использовать сканирование только по индексу в pg 9.2, вам понадобится многостолбцовый индекс в виде:
CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);
Этот вариант лучше в любом случае в большинстве случаев и в любой версии PostgreSQL. Из-за выравнивания данных добавление boolean
к integer
в индексе не приведет к росту индекса вообще. Добавленная выгода едва ли любой ценой.
Однако индексированные столбцы предотвращают обновления HOT (Heap Only Tuple). Скажем, UPDATE
изменяет только столбец в archived
. Если столбец не используется каким-либо индексом (каким-либо образом), строка может быть ГОРЯЧЕЙ обновлена. Иначе, этот ярлык не может быть использован. Я написал больше об горячих обновлениях в этом связанном ответе.
Так что, как всегда, это зависит от вашей рабочей нагрузки.