복붙노트

[SQL] PostgreSQL의에서 테이블의 행 수를 발견하는 빠른 방법

SQL

PostgreSQL의에서 테이블의 행 수를 발견하는 빠른 방법

나는 비율을 계산하기 위해 테이블의 행 수를 알 필요가있다. 총 수는 몇 가지 미리 정의 된 상수보다 큰 경우, 나는 상수 값을 사용합니다. 그렇지 않으면, 나는 실제 행 수를 사용합니다.

나는 테이블에서 선택 카운트 (*)를 사용할 수 있습니다. 하지만 내 상수 값은 500,000이고, 나는 많은 시간을 낭비하는 모든 행을 계산, 내 테이블에 5,000,000,000 행이있는 경우.

내 상수 값이 초과 될 때 빨리 계산을 중지 할 수 있습니까?

나는 단지 한이 주어진 한계 이하의 같은 행의 정확한 번호가 필요합니다. 카운트가 한계 이상이면 그렇지 않으면, 내가 대신 한계 값을 사용하고 가능한 한 빨리 대답을 할 수 있습니다.

이 같은:

SELECT text,count(*), percentual_calculus()  
FROM token  
GROUP BY text  
ORDER BY count DESC;

해결법

  1. ==============================

    1.큰 테이블에서 계산 행은 PostgreSQL의 느린 것으로 알려져있다. 때문에 MVCC의 성격에 행의 전체 수를 수행하는 정확한 번호를합니다. 그것은 귀하의 경우 것으로 보인다처럼 카운트가 정확하지 않을 경우 극적으로이 속도를 높일 수있는 방법이있다.

    큰 테이블에서 계산 행은 PostgreSQL의 느린 것으로 알려져있다. 때문에 MVCC의 성격에 행의 전체 수를 수행하는 정확한 번호를합니다. 그것은 귀하의 경우 것으로 보인다처럼 카운트가 정확하지 않을 경우 극적으로이 속도를 높일 수있는 방법이있다.

    대신 정확한 수를 얻는 (큰 테이블과 느림) :

    SELECT count(*) AS exact_count FROM myschema.mytable;
    

    이 (매우 빠르게) 같은 가까운 추정치를 얻을 수 :

    SELECT reltuples::bigint AS estimate FROM pg_class where relname='mytable';
    

    얼마나 가까이 추정치는 것은 충분히 ANALYZE 실행 여부에 따라 달라집니다. 그것은 매우 가까운 보통이다. PostgreSQL의 위키 FAQ를 참조하십시오. 또는 COUNT (*)의 성능을 위해 전용 위키 페이지입니다.

    PostgreSQL의 위키의 기사는 조금 실수였다됩니다. 다른 스키마에서 - 그것은 하나의 데이터베이스에 같은 이름의 여러 테이블이있을 수 있다는 가능성을 무시했다. 그 설명하기 위해 :

    SELECT c.reltuples::bigint AS estimate
    FROM   pg_class c
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = 'mytable'
    AND    n.nspname = 'myschema'
    
    SELECT reltuples::bigint AS estimate
    FROM   pg_class
    WHERE  oid = 'myschema.mytable'::regclass;
    

    빠르고, 간단하고, 안전하고, 더 우아한. 객체 식별자 유형에 대한 설명서를 참조하십시오.

    포스트 그레스 9.4+에서 사용 to_regclass ( 'myschema.mytable')는 유효하지 않은 테이블 이름에 대한 예외를 피하기 위해 :

    SELECT 100 * count(*) AS estimate FROM mytable TABLESAMPLE SYSTEM (1);
    

    @a_horse 주석처럼 pg_class 통계는 어떤 이유로하지 충분한 전류 경우, SELECT 명령에 새로 추가 된 조항 유용 할 수 있습니다. 예를 들면 :

    이것 만의 블록 개수의 행 선택 (예 1) 임의의 N %로 본다. 더 큰 샘플은 비용을 증가시키고 오류, 당신의 선택을 줄일 수 있습니다. 정확도는 더 요인에 따라 달라집니다

    대부분의 경우 pg_class의 평가는보다 빠르고 정확합니다.

    그리고 여부 ...

    예. 당신은 LIMIT와 하위 쿼리를 사용할 수 있습니다 :

    SELECT count(*) FROM (SELECT 1 FROM token LIMIT 500000) t;
    

    포스트 그레스는 실제로 n은 그렇지 않으면, 당신은 (예에서 500000) 최대 n 개의 행에 대한 정확한 현재 카운트를 얻을 주어진 제한을 초과하는 계산을 중지합니다. 아니 거의 최대한 빨리하지만 pg_class의 추정, 등.

  2. ==============================

    2.나는 실행하여 포스트 그레스 응용 프로그램에서 한 번 이런 짓을 :

    나는 실행하여 포스트 그레스 응용 프로그램에서 한 번 이런 짓을 :

    EXPLAIN SELECT * FROM foo;
    

    그런 다음 정규식 또는 유사한 로직 출력을 검사. 간단한 SELECT *를 들어, 출력의 첫 번째 줄의 모양은 다음과 같습니다

    Seq Scan on uids  (cost=0.00..1.21 rows=8 width=75)
    

    당신은 행을 사용할 수 = (\ D +) 만 실제 SELECT COUNT을, 반환되는 행의 수를 대략적으로 값 (*) 추정치 인 경우, 말,보다 1.5 배 당신의 임계 값 (또는 어떤 번호를 당신이 당신의 응용 프로그램에 대한 차종의 감각을 간주).

    쿼리의 복잡도에 따라,이 숫자는 적게 정확한 될 수 있습니다. 사실, 내 응용 프로그램에서, 우리가 그것을 알지도하는, 완전히 쓸모없는 그래서 부정확되었다 조인 복잡한 조건을 추가하는 방법을 우리가 전략을 포기했다, 그래서 우리가 반환 한 것입니다 얼마나 많은 행 (100)의 전력 내에서.

    쿼리에 대학원이 반환 얼마나 많은 행 오류의 몇 가지 합리적인 마진 내에서 예측할 수있는 간단한 충분한 경우, 그것은 당신을 위해 작동 할 수 있습니다.

  3. ==============================

    3.오라클, 당신은 반환되는 행의 수를 제한하기 위해 ROWNUM 사용할 수 있습니다. 나는 비슷한 구조뿐만 아니라 다른 SQL을에 존재하는 추측하고있다. 그래서, 당신이 준 예를 들어, 당신은 500,001에 반환되는 행의 수를 제한하고 카운트 (*)를 적용 할 수 있습니다 :

    오라클, 당신은 반환되는 행의 수를 제한하기 위해 ROWNUM 사용할 수 있습니다. 나는 비슷한 구조뿐만 아니라 다른 SQL을에 존재하는 추측하고있다. 그래서, 당신이 준 예를 들어, 당신은 500,001에 반환되는 행의 수를 제한하고 카운트 (*)를 적용 할 수 있습니다 :

    SELECT (case when cnt > 500000 then 500000 else cnt end) myCnt
    FROM (SELECT count(*) cnt FROM table WHERE rownum<=500001)
    
  4. ==============================

    4.참고이 블로그에서 가져옵니다.

    참고이 블로그에서 가져옵니다.

    당신은 행 수를 찾기 위해 쿼리에 아래 사용할 수 있습니다.

    pg_class를 사용 :

     SELECT reltuples::bigint AS EstimatedCount
        FROM   pg_class
        WHERE  oid = 'public.TableName'::regclass;
    

    pg_stat_user_tables 사용 :

    SELECT 
        schemaname
        ,relname
        ,n_live_tup AS EstimatedCount 
    FROM pg_stat_user_tables 
    ORDER BY n_live_tup DESC;
    
  5. ==============================

    5.당신은 쿼리 아래 (*없이 또는 열 이름)로 카운트를 얻을 수 있습니다.

    당신은 쿼리 아래 (*없이 또는 열 이름)로 카운트를 얻을 수 있습니다.

    select from table_name;
    
  6. ==============================

    6.어떻게 넓은 텍스트 열은 무엇입니까?

    어떻게 넓은 텍스트 열은 무엇입니까?

    많이는 데이터 스캔 (적어도 인덱스 스캔)을 피할 방법은별로 없다 BY 그룹과.

    내가 권하고 싶습니다 :

    편집하다:

    원래 질문은 확실히 당신의 편집과 일치하지 않습니다. 나는 당신이 카운트가하는 GROUP BY와 함께 사용하면, 그룹 당 항목의 수와 전체가 아닌 테이블에있는 항목의 수를 반환합니다 알고 있다면 아니에요.

  7. ==============================

    7.(위 2005 또는) SQL Server의 신속하고 신뢰할 수있는 방법은 다음과 같습니다

    (위 2005 또는) SQL Server의 신속하고 신뢰할 수있는 방법은 다음과 같습니다

    SELECT SUM (row_count)
    FROM sys.dm_db_partition_stats
    WHERE object_id=OBJECT_ID('MyTableName')   
    AND (index_id=0 or index_id=1);
    

    sys.dm_db_partition_stats에 대한 자세한 내용은 MSDN에 설명되어 있습니다

    쿼리는 (아마도) 분할 된 테이블의 모든 부분에서 행을 추가합니다.

    INDEX_ID = 0 순서화 테이블 (힙) 및 INDEX_ID = 1 순서 테이블 (클러스터 된 인덱스)이며

    더 빨리 (그러나 신뢰할 수없는) 방법은 여기에 자세히 설명되어 있습니다.

  8. from https://stackoverflow.com/questions/7943233/fast-way-to-discover-the-row-count-of-a-table-in-postgresql by cc-by-sa and MIT license