sql >> データベース >  >> RDS >> Mysql

Postgresl select count(*)時間のかかる

    2番目のステートメントは、行をカウントするためにテーブル全体をスキャンする必要があるため、長い時間がかかります。

    できることの1つは、インデックスを使用することです:

    CREATE INDEX ON tbl_oplog (deleted) INCLUDE (id);
    VACUUM tbl_oplog;  -- so you get an index only scan
    

    idと仮定します 主キーである場合は、count(*)を使用する方がはるかに優れています。 INCLUDEを省略します インデックスからの句。

    ただし、おそらく見積もりを使用するのが最善です:

    SELECT t.reltuples * freq.f AS estimated_rows
    FROM pg_stats AS s
       JOIN pg_namespace AS n
          ON s.schemaname = n.nspname
       JOIN pg_class AS t
          ON s.tablename = t.relname
             AND n.oid = t.relnamespace
       CROSS JOIN LATERAL
          unnest(s.most_common_vals::text::boolean[]) WITH ORDINALITY AS val(v,id)
       JOIN LATERAL
          unnest(s.most_common_freqs) WITH ORDINALITY AS freq(f,id)
             USING (id)
    WHERE s.tablename = 'tbl_oplog'
      AND s.attname = 'deleted'
      AND val.v = ?;
    

    これは、分布統計を使用して、目的のカウントを推定します。

    ちょうどページネーションに関するものであれば、正確なカウントは必要ありません。

    私のブログ を読む PostgreSQLでのカウントのトピックの詳細については。




    1. クラスタ化された列ストアインデックスからの削除のシリアル化

    2. ODBCレイヤーのテスト

    3. OracleDatabase19cのオプティマイザ

    4. SQL / MySQLでは、同じテーブルに1対1の関係を置かない理由はありますか?