Быстрее ли вызывать процедуру дважды и получать COUNT (*) при втором вызове или быстрее выполнять COUNT (*) OVER () при получении списка записей? (PostgreSQL) - PullRequest
0 голосов
/ 15 ноября 2018

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

По сути, сценарий заключается в том, что, когда мы хотим извлечь список записей из процедуры, быстрее / эффективнее вычислять общее количество записей из процедуры , когда мы выбираем список записей в одном запросе или лучше сначала получить список записей, а затем снова вызвать COUNT для той же процедуры (в 2 вызовах).

Какой из этих примеров более эффективен? Почему?

Пример 1

SELECT *, COUNT(1) OVER() AS total_rows FROM some_procedure();

Возвращает столбец total_rows в каждой строке вместе с остальными столбцами.

-или-

Пример 2

SELECT * FROM some_procedure();
SELECT COUNT(*) FROM some_procedure();

Этот способ требует 2 вызова, но не вычисляет столбец total_rows.

Кроме того, рассчитывается ли COUNT в Примере 1 для каждой записи или только один раз?

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Единственный способ узнать это - проверить.

Несмотря на то, что при многократных вызовах в базу данных возникают накладные расходы, чтение всех строк таблицы может быть довольно дорогим.Конечно, если в таблице 10 строк, то это не дорого.Миллиард строк - это другое дело.

Расчет count(*) в Postgres должен потребовать сканирования всех строк - и проверки на блокировку (для обработки параллельных транзакций).К сожалению, это довольно дорого.

Если вы читаете все строки, почему бы просто не сосчитать те, которые были возвращены?

0 голосов
/ 15 ноября 2018

Если функция возвращает только несколько строк (по сравнению с количеством строк в таблице, из которой она читает), я бы посчитал возвращенных строк:

with result as (
   select *
   from some_function()
)
select *, (select count(*) from result) as total_rows
from result;

Опять же, это имеет смысл, только если функция выполняет некоторые тяжелые действия, которые вы хотите выполнить только один раз и , количество строк достаточно мало (насколько это зависит от вашего сервера, всего, что в «многие тысячи», вероятно, в порядке, что-то вроде «миллионов строк», вероятно, не будет эффективным.

0 голосов
/ 15 ноября 2018

Есть много «это зависит», но, как правило, я заставляю базу данных выполнять работу, делая один вызов, а не несколько.

Одиночные вызовы позволяют оптимизировать БД, если это возможно.

При множественных вызовах тратится много времени на маршалинг и демаршалинг параметров, сетевой трафик, когда БД интерпретирует вызов, вызывая прерывание обратно в вызывающий процесс для выполнения второго вызова.

Но тестирование - это единственный способ узнать наверняка.

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