Which index does MySQL count (*) choose?

Source: Internet
Author: User

Today, when querying a table row count, it is found that count (1) and COUNT (*) execution efficiency are the same. There's a difference between this and Oracle. Then look at the execution plan in two ways:

Mysql> Select COUNT (1) from customer;+----------+| Count (1) |+----------+|   150000 |+----------+1 row in Set (0.03 sec) mysql> flush tables; Query OK, 0 rows Affected (0.00 sec) mysql> Select COUNT (*) from customer;+----------+| COUNT (*) |+----------+|   150000 |+----------+1 row in Set (0.03 sec)

To view the execution plan:

Mysql> Explain select COUNT (1) from customer;+----+-------------+----------+-------+---------------+------------ ---+---------+------+--------+-------------+| ID | Select_type | Table | Type | Possible_keys | Key | Key_len | Ref | Rows | Extra |+----+-------------+----------+-------+---------------+---------------+---------+------+--------+--------  -----+| 1 | Simple | Customer | Index | NULL | I_c_nationkey | 5 | NULL | 151191 | Using index |+----+-------------+----------+-------+---------------+---------------+---------+------+--------+-- -----------+1 Row in Set (0.00 sec) mysql> Explain select count (*) from customer;+----+-------------+----------+------ -+---------------+---------------+---------+------+--------+-------------+| ID | Select_type | Table | Type | Possible_keys | Key | Key_len | Ref | Rows | Extra |+----+-------------+----------+-------+---------------+---------------+---------+------+--------+-------------+| 1 | Simple | Customer | Index | NULL | I_c_nationkey | 5 | NULL | 151191 | Using index |+----+-------------+----------+-------+---------------+---------------+---------+------+--------+-- -----------+1 Row in Set (0.00 sec) mysql> Show index from customer;+----------+------------+---------------+-------- ------+-------------+-----------+-------------+----------+--------+------+------------+---------+-------------- -+| Table | Non_unique | Key_name | Seq_in_index | column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |+----------+------------+---------------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+|          Customer | 0 |            PRIMARY | 1 | C_custkey |      A |     150525 | NULL |      NULL | |         BTREE |               | ||          Customer | 1 |            I_c_nationkey | 1 | C_nationKey |          A |     47 | NULL | NULL | YES |         BTREE |               | |+----------+------------+---------------+--------------+-------------+-----------+-------------+----------+--- -----+------+------------+---------+---------------+2 rows in Set (0.08 sec)

It is found that either count (1) or COUNT (*) is walking I_c_nationkey this index. Usually when we retrieve the data is the primary key index efficiency is high, then we force the primary key index to see:

Mysql> Select COUNT (*) from the Customer Force index (PRIMARY); +----------+| COUNT (*) |+----------+|   150000 |+----------+1 row in Set (0.68 sec) mysql> Explain select count (*) from Customer Force index (PRIMARY), +----+---- ---------+----------+-------+---------------+---------+---------+------+--------+-------------+| ID | Select_type | Table    | type  | possible_keys | key     | key_len | ref  | rows   | Extra       |+----+-------------+----------+-------+---------------+---------+---------+------+--------+--------- ----+|  1 | Simple      | customer | index | NULL          | PRIMARY | 4       | NULL | 150525 | Using index |+----+-------------+----------+-------+---------------+---------+---------+------+--------+-------- -----+1 Row in Set (0.00 sec)

You can see the index of the primary key when the efficiency is poor. So what is it for?
Usually when we retrieve a column, basically equivalent or range query, then the index cardinality of the index is necessarily highly efficient. However, when you do count (*), you do not retrieve a specific row or range. Then select an index pair with a small cardinality
Count operations are more efficient. When you do the count operation, MySQL iterates through each leaf node, so the smaller the cardinality, the higher the efficiency. MySQL non-clustered index leaf node holds the primary key ID, so it needs to be retrieved two times index. But this is relative to traversing the primary key index. Timely retrieval two times index efficiency is also faster than simply retrieving the primary key index.
Then take a table as proof:

Mysql> Explain select COUNT (*) from lineitem;+----+-------------+----------+-------+---------------+------------ --+---------+------+---------+-------------+| ID | Select_type | Table | Type | Possible_keys | Key | Key_len | Ref | Rows | Extra |+----+-------------+----------+-------+---------------+--------------+---------+------+---------+--------  -----+| 1 | Simple | LineItem | Index | NULL | I_l_shipdate | 4 | NULL | 6008735 | Using index |+----+-------------+----------+-------+---------------+--------------+---------+------+---------+-- -----------+1 Row in Set (0.00 sec) mysql> Show index from lineitem;+----------+------------+-----------------------+ --------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---- -----------+| Table | Non_unique | Key_name | Seq_in_index | column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_commENT |+----------+------------+-----------------------+--------------+---------------+-----------+-------------+- ---------+--------+------+------------+---------+---------------+|          LineItem | 0 |            PRIMARY | 1 | L_orderkey |     A |     2997339 | NULL |      NULL | |         BTREE |               | ||          LineItem | 0 |            PRIMARY | 2 | L_linenumber |     A |     5994679 | NULL |      NULL | |         BTREE |               | ||          LineItem | 1 |            I_l_shipdate | 1 | L_shipdate |        A |     5208 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_suppkey_partkey | 1 | L_partkey |      A |     428191 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_suppkey_partkey | 2 | L_suppkey |     A |     1998226 | NULL | NULL | YES | BTREE |               | ||          LineItem | 1 |            I_l_partkey | 1 | L_partkey |      A |     461129 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_suppkey | 1 | L_suppkey |       A |     19213 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_receiptdate | 1 | L_receiptdate |          A |     17 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_orderkey | 1 | L_orderkey |     A |     2997339 | NULL |      NULL | |         BTREE |               | ||          LineItem | 1 |            i_l_orderkey_quantity | 1 | L_orderkey |     A |     1998226 | NULL |      NULL | |         BTREE |               | ||          LineItem | 1 |            i_l_orderkey_quantity | 2 | l_quantity |     A | 5994679 | NULL | NULL | YES |         BTREE |               | ||          LineItem | 1 |            I_l_commitdate | 1 | L_commitdate |        A |     7836 | NULL | NULL | YES |         BTREE |               | |+----------+------------+-----------------------+--------------+---------------+-----------+-------------+---- ------+--------+------+------------+---------+---------------+12 rows in Set (0.96 sec)
Here a look at L_shipdate is not the base of the smallest ah, but this statistic information is not accurate. Let's look at it in SQL.

Mysql> Select COUNT (Distinct (l_shipdate)) from lineitem;+-----------------------------+| COUNT (Distinct (l_shipdate)) |+-----------------------------+|                        2526 |+-----------------------------+1 row in Set (0.01 sec)
What about the columns that are smaller than him?

Mysql> Select COUNT (Distinct (l_receiptdate)) from lineitem;+--------------------------------+| COUNT (Distinct (l_receiptdate)) |+--------------------------------+|                           2554 |+--------------------------------+1 row in Set (0.01 sec)

Other will not look, here again that MySQL chose the base small index.


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Which index does MySQL count (*) choose?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.