0

はい、この質問は次のスレッドに似ています: COUNT(*) vs. COUNT(1) vs. COUNT(pk): which is better? とありますが、これはちょっと違います。

私の先輩は、結果を得ることができないとcount(PrimaryKey)仮定して、普通に行うよりも何とか速いと言いました。これは本当ですか?PrimaryKeyNULLcount(*)

これが本当なら、すべての RDBMS に当てはまりますか? 可能であれば(準)公式ドキュメントを参照してください。

4

2 に答える 2

2

いいえ。これは、構文間の混乱に基づく、永続的な誤解のようです。

SELECT * FROM ...

SELECT COUNT(*) FROM ...

最初のケースで*は、すべての列を参照し、それらを返すには、単一の列を返すよりも多くのリソースが必要です。2 番目のケースでCOUNT(*)は、単に「すべての行をカウントする」の省略形です。COUNT(*)1 つの列だけを調べる必要があるのに、データベース エンジンにすべての行のすべての列を調べるように何らかの方法で指示するというのは、誤った信念ですCOUNT(<pk_field>)

ここでは、SQL-92 標準を参照する SO に関する他のコメントが多数ありますCOUNT(*)。これは、テーブルのカーディナリティのみを参照する必要があることを明示的に示しているため、少なくとも理論的には、データベース エンジンはそれを認識して最適化できるはずです。

私が知る限り、どちらの場合も、ほとんどのデータベース エンジン ( PostgresOracleMySQL InnoDB ) はインデックス スキャンを実行して行数をカウントします。PK を指定すると、そのインデックスが使用されます。を使用するだけの場合COUNT(*)、クエリプランナーはテーブル全体にまたがるインデックスを選択します*が、パフォーマンスは同じである必要があります。

これに対する唯一の例外は、MyISAM テーブルを使用する MySQL です。これらのテーブルは行数をキャッシュするため、COUNT(*)非常に高速です。ただし、クエリ プランナーはCOUNT(<field>)、ここで<field>は null 以外の列を、テーブル全体のサイズに対する要求として認識し、その場合もキャッシュを使用します。(ソース) 繰り返しますが、パフォーマンスに違いはありません。

* 理論的には、そのようなインデックスがなけれCOUNT(*)ば非常に遅くなりますが、その場合はCOUNT(<pk>)定義上不可能です

于 2012-09-14T06:06:11.740 に答える
0

いくつかの理由で問題ではありません。まず、表記 --COUNT(1)COUNT(*)-- はどちらも間違った構文です。SUM集計について同じ質問を考えてみましょう。ああ、SUM(*)意味がありません。なぜ?総和は代入の反復実行であるため

for( int columnValue : columnList )
   currentSum = currentSum + columnValue;

一方、COUNT集計の場合は次のようになります

for( Tuple t : tupleList )
   currentSum = currentSum + 1;

したがって、COUNT集計にはパラメーターをまったく指定しないでください。

次に、count distinct など、あらゆる種類の構文上の癖があります。これは、2 つの連続したアクション (個別のタプルを選択してから集計する) を 1 つの操作にまとめようとした SQL 設計者の無能さを示しています。

それが問題にならない 2 つ目の理由は、実際にはパフォーマンスの低いクエリが無数に発生することであり、COUNT(1)vsCOUNT(*)がボトルネックになることは決してないからです。

于 2012-09-13T18:49:16.877 に答える