PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Най-добрият начин да получите резултат, преди да се приложи LIMIT

Чист SQL

Нещата се промениха от 2008 г. Можете да използвате функция за прозорец, за да получите пълния брой и ограничен резултат в една заявка. Въведен с PostgreSQL 8.4 през 2009 г.

SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  <some condition>
ORDER  BY <some col>
LIMIT  <pagesize>
OFFSET <offset>;

Имайте предвид, че това може да бъде значително по-скъпо, отколкото без общия брой . Всички редове трябва да бъдат преброени и възможен пряк път, вземащ само горните редове от съответстващ индекс, може вече да не е полезен.
Няма голямо значение при малки таблици или full_count <=OFFSET + LIMIT . Има значение за значително по-голям full_count .

Ъглов калъф :когато OFFSET е поне толкова голям, колкото броя на редовете от основната заявка, без ред се връща. Така че вие ​​също не получавате full_count . Възможна алтернатива:

  • Изпълнете заявка с LIMIT/OFFSET и получете общия брой редове

Последователност от събития в SELECT заявка

(0. CTE се оценяват и материализират отделно. В Postgres 12 или по-нова версия, плановникът може да вгради тези като подзаявки, преди да започне работа.) Не тук.

  1. WHERE клауза (и JOIN условия, макар и никакви във вашия пример) филтрирайте квалифициращите редове от основната таблица(и). Останалото се основава на филтрираното подмножество.

( 2. GROUP BY и агрегатните функции ще отидат тук.) Не тук.

( 3. Други SELECT списъчните изрази се оценяват въз основа на групирани / обобщени колони.) Не тук.

  1. Функциите на прозореца се прилагат в зависимост от OVER клауза и спецификацията на рамката на функцията. Простият count(*) OVER() се основава на всички квалификационни редове.

  2. ORDER BY

( 6. DISTINCT или DISTINCT ON би отишъл тук.) Не тук.

  1. LIMIT / OFFSET се прилагат въз основа на установения ред за избор на редове за връщане.

LIMIT / OFFSET става все по-неефективно с нарастващ брой редове в таблицата. Помислете за алтернативни подходи, ако имате нужда от по-добра производителност:

  • Оптимизиране на заявката с OFFSET върху голяма таблица

Алтернативи за получаване на окончателно броене

Има напълно различни подходи за получаване на броя на засегнатите редове (не пълният брой преди OFFSET &LIMIT бяха приложени). Postgres има вътрешно счетоводство колко реда са засегнати от последната SQL команда. Някои клиенти могат да имат достъп до тази информация или сами да броят редове (като psql).

Например, можете да извлечете броя на засегнатите редове в plpgsql веднага след изпълнение на SQL команда с:

GET DIAGNOSTICS integer_var = ROW_COUNT;

Подробности в ръководството.

Или можете да използвате pg_num_rows в PHP . Или подобни функции в други клиенти.

Свързано:

  • Изчислете броя на редовете, засегнати от груповата заявка в PostgreSQL


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как работи Width_Bucket() в PostgreSQL

  2. ClassNotFoundException с PostgreSQL и JDBC

  3. Инсталации с висока достъпност на PostgreSQL Patroni

  4. Попълване на поле Many2many (odoo 8)

  5. Ruby on Rails:Има ли начин да се изтеглят елементи от базата данни и да се върнат в определен ред?