[SQL] LIMIT이 적용되기 전에 가장 좋은 방법은 결과 수를 얻을 수 있습니다
SQLLIMIT이 적용되기 전에 가장 좋은 방법은 결과 수를 얻을 수 있습니다
DB를에서 오는 데이터를 페이징하면 페이지 점프 컨트롤을 렌더링 할 수있을 것입니다 얼마나 많은 페이지를 알아야합니다.
현재 내가 두 번, 한 번에 전체 결과를 결정하는 계수 ()에 싸여 쿼리를 실행하여 그렇게하고, 한계와 두 번 다시 나는 현재 페이지에 필요한 바로 결과를 얻을 적용했다.
이것은 비효율적 인 것 같다. LIMIT이 적용되기 전에 반환 된 얼마나 많은 결과를 결정하는 더 좋은 방법이 있나요?
나는 PHP와 포스트 그레스를 사용하고 있습니다.
해결법
-
==============================
1.당신은 풀 카운트 한 쿼리에 제한 결과를 얻기 위해 윈도우 기능을 사용할 수 있습니다 2008 년부터 상황이 바뀌었다. 2009 년 PostgreSQL를 8.4로 발표했다.
당신은 풀 카운트 한 쿼리에 제한 결과를 얻기 위해 윈도우 기능을 사용할 수 있습니다 2008 년부터 상황이 바뀌었다. 2009 년 PostgreSQL를 8.4로 발표했다.
SELECT foo , count(*) OVER() AS full_count FROM bar WHERE <some condition> ORDER BY <some col> LIMIT <pagesize> OFFSET <offset>;
이 총 수없는보다 훨씬 더 비쌀 수 있습니다. 모든 행은 계산해야하고, 일치하는 인덱스에서 바로 상위 행을 복용 가능한 바로 가기가 더 이상 도움이되지 않을 수 있습니다. 문제가 훨씬 작은 테이블 또는 full_count와 <=가 + LIMIT를 OFFSET하지 않습니다. 실질적으로 더 큰 full_count에 대한 사항.
코너의 경우 : OFFSET은 기본 쿼리에서 행의 수와 같은 큰대로 적어도 때, 어떤 행이 반환되지 않습니다. 그래서 당신은 또한 더 full_count를 얻을 수 없습니다. 가능한 대안 :
(0 CTE를 평가하고 구체화 별도.에서 포스트 그레스 12 이상 플래너 직장에 가기 전에 하위 쿼리와 같은 사람들을 인라인 수 있습니다.) 여기가 아님.
(2. GROUP BY 및 집계 함수는 여기에 갈 것입니다.) 여기가 아님.
(3. 기타 SELECT리스트 표현식은 그룹화 / 집계 열을 기반으로, 평가됩니다.) 여기가 아님.
(6. DISTINCT 또는 DISTINCT ON 여기에 갈 것입니다.) 여기가 아님.
LIMIT는 / OFFSET은 테이블의 행의 수가 증가하고 점점 비효율적이된다. 당신이 더 나은 성능을 필요로하는 경우 다른 방법을 고려 :
영향을받는 행의 수 (OFFSET 및 LIMIT이 적용되기 전에 아니라 풀 카운트)를 얻기 위해 완전히 다른 접근 방법이있다. 포스트 그레스는 마지막 SQL 명령에 의해 영향을받는 행 수를 내부 부기가 있습니다. 일부 클라이언트는이 정보에 액세스하거나 (psql를 같은) 행 자체를 셀 수 있습니다.
예를 들어, 당신은 즉시로 SQL 명령을 실행 한 후 plpgsql에 영향을받는 행의 수를 검색 할 수 있습니다 :
GET DIAGNOSTICS integer_var = ROW_COUNT;
매뉴얼의 세부 사항.
또는 당신은 PHP에서 pg_num_rows를 사용할 수 있습니다. 다른 클라이언트에서 또는 유사한 기능.
관련 :
-
==============================
2.내 블로그에 설명 된 바와 같이, MySQL은 SQL_CALC_FOUND_ROWS라는 기능이 있습니다. 이 두 번 쿼리를 수행 할 필요성을 제거하지만 여전히 제한 조항이 일찍 중단 할 수했을 경우에도, 그 entireity에 쿼리를 할 필요가있다.
내 블로그에 설명 된 바와 같이, MySQL은 SQL_CALC_FOUND_ROWS라는 기능이 있습니다. 이 두 번 쿼리를 수행 할 필요성을 제거하지만 여전히 제한 조항이 일찍 중단 할 수했을 경우에도, 그 entireity에 쿼리를 할 필요가있다.
지금까지 내가 아는 한, PostgreSQL을위한 유사한 기능이 없습니다. 하고 AN, DB를 적어도 1010 개 행을 인출한다는 것을 의미한다 "1000 LIMIT 10 OFFSET"그것은 단지 당신에게 (10)을 제공하는 경우에도 : 매김을 할 때 조심하는 것은 (가장 일반적인 것은있는 LIMIT는 사용 IMHO입니다). 할 수있는 더 성능이 좋은 방법은 당신이 이전 행 (이 경우 1000)에 의해 주문하는 행의 값을 기억하고이 같은 쿼리를 다시 작성하는 것입니다 : "... WHERE order_row> value_of_1000_th LIMIT 10". (아니, 당신은 문제를 이동 한 경우) 장점은 "order_row는"대부분의 아마 색인이 있다는 점이다. 새로운 요소가 페이지 뷰 사이에 추가하는 경우,이 동기화에서 조금 얻을 수있는 단점은 (그러나 다시, 그것은 방문자에 의해 관찰하지 않을 수와 큰 성능을 얻을 수 있습니다).
-
==============================
3.당신은 때마다 COUNT () 쿼리를 실행하지 않음으로써 성능 저하를 완화 할 수있다. , 페이지 수를 캐시 쿼리를 다시 실행 오분 전에 말한다. 당신 인서트의 거대한 숫자를보고하지 않는 한, 그건 그냥 잘 작동합니다.
당신은 때마다 COUNT () 쿼리를 실행하지 않음으로써 성능 저하를 완화 할 수있다. , 페이지 수를 캐시 쿼리를 다시 실행 오분 전에 말한다. 당신 인서트의 거대한 숫자를보고하지 않는 한, 그건 그냥 잘 작동합니다.
-
==============================
4.포스트 그레스는 이미 일을 캐싱의 일정 금액을 수행하기 때문에, 방법의이 유형은 보이는만큼 비효율적 없습니다. 확실히 실행 시간을 두 배로 아닙니다. 내가 증거를 보았다 그래서 우리는 우리의 DB 층에 내장 된 타이머가있다.
포스트 그레스는 이미 일을 캐싱의 일정 금액을 수행하기 때문에, 방법의이 유형은 보이는만큼 비효율적 없습니다. 확실히 실행 시간을 두 배로 아닙니다. 내가 증거를 보았다 그래서 우리는 우리의 DB 층에 내장 된 타이머가있다.
-
==============================
5.당신이 페이징의 목적을 위해 알아야 할, 나는이 한 번 전체 쿼리를 실행하는 서버 측 캐시로 디스크에 데이터를 기록, 다음 페이징 메커니즘을 통해 것을 공급 좋을 것보고.
당신이 페이징의 목적을 위해 알아야 할, 나는이 한 번 전체 쿼리를 실행하는 서버 측 캐시로 디스크에 데이터를 기록, 다음 페이징 메커니즘을 통해 것을 공급 좋을 것보고.
당신이 (> X 레코드가있는 경우 즉, 오류를 다시 제공) 사용자에게 데이터를 제공할지 여부를 결정하기위한 목적으로 COUNT 쿼리를 실행하는 경우, 당신은 COUNT 접근 방식을 고수 할 필요가있다.
from https://stackoverflow.com/questions/156114/best-way-to-get-result-count-before-limit-was-applied by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 열 수가 다른 두 개의 테이블을 Unioning (0) | 2020.03.14 |
---|---|
[SQL] 다른 행에 다른 조건을 충족하는 값을 선택? (0) | 2020.03.14 |
[SQL] 어떻게 SQL 열 이름을 처리하는 것을 SQL 키워드처럼? (0) | 2020.03.14 |
[SQL] 합니까 PostgreSQL을 지원 "악센트를 구분"정렬? (0) | 2020.03.14 |
[SQL] 오라클과 페이징 (0) | 2020.03.14 |