ホームページ >データベース >mysql チュートリアル >MySQL の count(*)、count(1)、count(col) の違いは何ですか?

MySQL の count(*)、count(1)、count(col) の違いは何ですか?

WBOY
WBOY転載
2023-05-26 13:37:081561ブラウズ

    count 関数

    COUNT(式): クエリされたレコードの総数を返します。式パラメータはフィールドまたは * 記号です。

    テスト

    MySQL バージョン: 5.7.29

    ユーザー テーブルを作成し、100 万個のデータを挿入します。そのうち性別フィールドの 50 万行は null です。 of

    CREATE TABLE `users` (
      `Id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `name` varchar(32) DEFAULT NULL COMMENT '名称',
      `gender` varchar(20) DEFAULT NULL COMMENT '性别',
      `create_date` datetime DEFAULT NULL COMMENT '创建时间',
      PRIMARY KEY (`Id`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户表';

    count(*)

    MySQL 5.7.18 より前では、InnoDB はクラスター化インデックスをスキャンすることによってステートメントを処理していました。 SELECT COUNT(*) MySQL 5.7.18 以降、インデックスまたはオプティマイザ ヒントがオプティマイザに別のインデックスを使用するように指示しない限り、InnoDB は利用可能な最小のセカンダリ インデックスを走査することによって SELECT COUNT(*) ステートメントを処理します。セカンダリ インデックスが存在しない場合は、クラスター化インデックスがスキャンされます。
    一般的な意味は、セカンダリ インデックスがある場合はセカンダリ インデックスを使用することです。複数のセカンダリ インデックスがある場合は、コストを削減するために最小のセカンダリ インデックスが優先されます。セカンダリ インデックスがない場合は、クラスタ化インデックスを使用します。

    次のテストは、これらのビューを検証するために使用されます。

    まず、Id の主キーインデックスしかない場合に実行プランをクエリしてみると、

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    タイプがインデックスであることがわかります。キーは PRIMARY、つまり主キー インデックスが使用されることを意味します (key_len=8)。

    次に、名前フィールドにインデックスを追加し、再度実行プランを使用して表示します。

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    インデックスも使用されていることがわかりますが、インデックスはフィールドのインデックス名 key_len=99 を使用します。

    次に、name フィールドのインデックスを保持したまま、create_date フィールドにインデックスを追加し、実行計画を再度確認します。

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    #今度は、 create_date フィールドには key_len=6 でインデックスが付けられます。

    上記でどのインデックスが使用されたとしても、NULL 値が含まれているかどうかに関係なく、最終的にクエリされる行の総数は 100 万行になります。

    count(1)

    count(1) は count(*) と同じクエリ結果を持ち、NULL 値が含まれているかどうかに関係なく、最終的に 100 万個のデータを返します。

    count(col)

    count(col) は特定の列の値をカウントします。これは 3 つの状況に分けられます。

    count(id): ID をカウントします

    クエリ結果は count(*) と同じで、最終的には 100 万個のデータが返されます。

    count(indexcol): インデックス付きフィールドの統計

    Use count (名前) クエリの実行計画は次のとおりです。

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    インデックス フィールドが統計に使用され、インデックスもヒットしていることがわかります。
    列の名前フィールドを NULL に設定し、カウント クエリを実行すると、結果は 999999

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    次に、この列の NULL 値を空に設定します。文字列を入力し、カウント クエリを実行すると、結果は 1000000

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    を返します。つまり、インデックス フィールドを使用して行数をカウントするだけで、インデックスにヒットする可能性があります。 、NULL 値ではない行の数のみをカウントします。

    count(normal col): インデックスのないフィールドをカウントする

    インデックスのないフィールドをカウントする場合、インデックスは使用されず、NULL 値ではない行数のみがカウントされます。数えられる。

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    Count(1) と count(*) のトレードオフ

    以前にどこで見聞きしたのかわかりませんが、count(1) count(*) よりも優れている count(*) は効率が高いというのは間違った認識で、公式サイトには InnoDB は SELECT COUNT( *) と SELECT COUNT(1) の操作を同じように処理するという記載があります。パフォーマンスに違いはありません。
    翻訳 要するに、InnoDB は SELECT COUNT(*) と SELECT COUNT(1) の操作を同じ方法で処理し、パフォーマンスに違いはありません。

    MyISAM テーブルの場合、COUNT(*) は、1 つのテーブルから取得する場合、他の列が取得されず、句がない場合に非常に早く返されるように最適化されています。この最適化は、ストレージ エンジンのため、MyISAM テーブルにのみ適用されます。正確な行数が保存され、非常に迅速にアクセスできます。 COUNT(1) は、最初の列が NOT NULL として定義されている場合にのみ、同じ最適化を実行します。 ----MySQL 公式 Web サイトより
    これらの最適化は、where や group by がないという前提に基づいています。

    Alibaba の開発仕様にも記載されています

    MySQL の count(*)、count(1)、count(col) の違いは何ですか?

    したがって、開発中に count(*) を使用できる場合は、単に count(*) を使用してください。 ##

    以上がMySQL の count(*)、count(1)、count(col) の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。