Why SELECT COUNT(*) is much slower than SELECT with a WHERE clause in MySQL?

emmmsir :

There's the table.

CREATE TABLE `refdata` (
    `id` VARCHAR(36) NOT NULL COLLATE 'utf8_unicode_ci',
    `uid` INT NOT NULL,
    `data` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
    `ref_akid` TEXT NOT NULL COLLATE 'utf8_unicode_ci',
    `ref_version` VARCHAR(16) NOT NULL COLLATE 'utf8_unicode_ci',
    `remote_addr` VARCHAR(32) NOT NULL COLLATE 'utf8_unicode_ci',
    `fetched_at` TIMESTAMP NULL,
    `created_at` TIMESTAMP NULL,
    PRIMARY KEY (`id`) USING BTREE,
    INDEX `link_to_user` (`uid`) USING BTREE,
    CONSTRAINT `link_to_user` FOREIGN KEY (`uid`) REFERENCES `selfdb`.`admin_users` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

The id is an UUID and the data is take about 1Mb. So the table is about 1.3G with 1.3M rows. Here's the result.

mysql> SELECT COUNT(*) FROM refdata;
+----------+
| COUNT(*) |
+----------+
|  1381991 |
+----------+
1 row in set (1 min 9.49 sec)

mysql> SELECT COUNT(*) FROM refdata WHERE uid > 0;
+----------+
| COUNT(*) |
+----------+
|  1382097 |
+----------+
1 row in set (0.29 sec)

Why the previous query is much slower than the second query?

P.S. There an app running and insert data. Are there some reasons about the table lock?


Here are explains.

mysql> explain SELECT COUNT(*) FROM refdata;
+----+-------------+------------+------------+-------+---------------+--------------+---------+------+---------+----------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key          | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+------------+------------+-------+---------------+--------------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | refdata    | NULL       | index | NULL          | link_to_user | 4       | NULL | 1387770 |   100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+--------------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain SELECT COUNT(*) FROM refdata WHERE uid > 0;
+----+-------------+------------+------------+-------+---------------+---------------+---------+------+--------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys | key           | key_len | ref  | rows   | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------+---------------+---------+------+--------+----------+--------------------------+
|  1 | SIMPLE      | refdata    | NULL       | range | link_to_user  | link_to_user  | 4       | NULL | 693885 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+---------------+---------------+---------+------+--------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain SELECT * FROM refdata;
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------+
|  1 | SIMPLE      | refdata    | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1387771 |   100.00 | NULL  |
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> explain SELECT * FROM refdata WHERE uid > 0;
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table      | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | refdata    | NULL       | ALL  | link_to_user  | NULL | NULL    | NULL | 1387774 |    50.00 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)


George Pant :

That is the expected behavior for InnoDB tables.

InnoDB engine supports transactions.So when you perform COUNT(*), the table must be fully scanned to avoid counting rows that are not yet commited.

But when you specify a filtering condition with WHERE only the filtered rows need to be counted and since UID in your case is an indexed column that is much faster.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Why is WHERE clause with OR so much slower than UNION ALL?

Adding OR clause to where condition is much slower than two individual queries

SELECT COUNT in WHERE CLAUSE in Eloquent

Select statement in Promela much slower than the equivalent if statement?

Postgresql why is INNER JOIN so much slower than WHERE

Mysql select alias in where clause

MySQL select query in where clause

MySQL select from where clause on

Using the result of a select clause for a where clause to MySQL

Expression tree for groupby with where clause and than select

SQL Select Count Distinct with WHERE clause

MySQL SELECT id + SELECT * WHERE id IN (...) seems faster than plain SELECT *. Why?

Why having a default clause in a goroutine's select makes it slower?

mysql query to select user count with Like clause

Mysql: Select Count And IN Clause in One Query

Mysql select unique columns from where clause

Select all rows with WHERE clause in MySQL

Optimize MYSQL query TIMEDIFF in Select and where Clause

MySQL manually add id in clause "WHERE IN (SELECT ...)"

In MYSQL, is it possible to SELECT something that will be defined in the WHERE clause?

Mysql query select sum where clause

How to get a row count of another table, using SELECT column as a WHERE clause using MySQL

Why is numpy select is slower than a custom function via apply method?

Why is BufferedReader read() much slower than readLine()?

Why is BufferedReader read() much slower than readLine()?

why is ExpandoObject much slower than Dictionary?

Why is writing to memory much slower than reading it?

Why is bokeh so much slower than matplotlib

Why is NOT IN much slower than IN in SQL query