问题引入:
有两个相同结构的表account_primary和account_copy,其中表account_primary对id列加了主键,表account_copy无索引信息,且两张表中的记录数相同
场景一:分别对上述两张表进行count运算
预期结果:
含有主键列的表的计算速度高于无索引的表
开始测试:
对两张表分别执行count运算
mysql> select count(*) from account_primary;
+----------+
| count(*) |
+----------+
| 50577 |
+----------+
1 row in set (0.03 sec)
mysql> select count(*) from account_copy;
+----------+
| count(*) |
+----------+
| 50577 |
+----------+
1 row in set (0.05 sec)
可以看出account_primary的执行速度快于account_copy的执行速度,符合预期结果。
原因分析:
分别查看两次运行的执行计划
account_primary:
account_copy:
从执行计划可以看出:account_primary的运行是通过全扫描该索引,获取到该表有多少条记录的信息,而account_copy的运行是通过全扫描数据表获取该表有多少条记录的信息。索引的大小比表大小小的多,在更大范围内遍历的速度显然慢于在更小范围内遍历的速度。
结论:
以上利用了索引比表小的多的特点,对相关表存放序列值的非空字段SEQ_ID建一个索引,然后全扫描该索引即可。
场景二:无where条件,count(*)和count(col)效率比较
mysql> select count(id) from account_primary;
+-----------+
| count(id) |
+-----------+
| 50577 |
+-----------+
1 row in set (0.03 sec)
mysql> flush tables;
Query OK, 0 rows affected (0.00 sec)
mysql> select count(*) from account_primary;
+----------+
| count(*) |
+----------+
| 50577 |
+----------+
1 row in set (0.03 sec)
场景三:有where条件,count(*)和count(col)效率比较
mysql> select count(*) from account_copy where id=1080664;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.04 sec)
mysql> flush tables;
Query OK, 0 rows affected (0.00 sec)
mysql> select count(id) from account_copy where id=1080664;
+-----------+
| count(id) |
+-----------+
| 1 |
+-----------+
1 row in set (0.05 sec)
结论:
1.在不加where限制条件的情况下,count(*)与count(col)基本可以认为是等价的
2.在有where限制条件的情况下,count(*)会比count(col)快很多
3.无论何种情况使用count(*)即可
4.引擎的选择:MyISAM引擎下执行select count(*)操作会快于InnoDB引擎,因为MyISAM存在内部计数器来记录表记录总量
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23073137/viewspace-721494/
,如需转载,请注明出处,否则将追究法律责任。