欢迎各位兄弟 发布技术文章
这里的技术是共享的
-- 执行计划一样,所以:应该是差不多,不过我们习惯不用*,而用常数(1)! mysql> explain select count(*) from t_Groupon_order\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t_Groupon_order type: index possible_keys: NULL key: ONLINE_ID_KEY key_len: 9 ref: NULL rows: 7788848 Extra: Using index 1 row in set (0.00 sec) mysql> explain select count(1) from t_Groupon_order\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t_Groupon_order type: index possible_keys: NULL key: ONLINE_ID_KEY key_len: 9 ref: NULL rows: 7788882 Extra: Using index 1 row in set (0.00 sec) 这个只能说跟数据库的实现有关系。 在过去低版本的实现当中,count(1)可能要快于count(*), 但是高版本的实现里头,两者可能完全一样。 这要看DBMS如何处理了, MSSql是这样定义的: COUNT(*):返回记录总数,不会读取行上的任何信息, COUNT(1):返回记录总数,但是会在每一行读取1 MySql,只要不是读取行的所有列,还是优先使用COUNT(*) 由于数据库引擎的不同结果也会不一样,所以测试了 MyISAM 和 InnoDB 两种引擎,后面是测试过程的输出,结论如下: 1. InnoDB 对于各种形式的 count 均一样,需要全表扫描进行计算,对于非主键的列进行计算结果反而更快(可能是缓存的影响?) 2. MyISAM 对于非主键的列进行 count 会慢一些,其它的形式均很快。对于 count(*) 肯定是直接读取数据库的“行数”属性,其它的也是 0 秒的形式不大清楚其实际计算过程 3. 对于不同的数据库系统和不同的引擎可能实现上不同,所以此题目所说的比较需要基于不同的环境进行 ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 31 to server version: 5.1.6-alpha-nt-max Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> use test; Database changed mysql> mysql> drop table if exists tb_myisam; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE tb_myisam ( -> id int(10) NOT NULL auto_increment, -> name char(10) default NULL, -> PRIMARY KEY (id) -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.05 sec) mysql> mysql> drop table if exists tb_innodb; Query OK, 0 rows affected (0.05 sec) mysql> CREATE TABLE tb_innodb ( -> id int(10) NOT NULL auto_increment, -> name char(10) default NULL, -> PRIMARY KEY (id) -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.08 sec) mysql> mysql> drop procedure if exists testdata; Query OK, 0 rows affected (0.00 sec) mysql> delimiter $$ mysql> create procedure testdata() -> begin -> declare i int; -> set i = 0; -> while i <5000000 -> do -> insert into tb_myisam(name) values(ceil(rand()*100)); -> set i = i + 1; -> end while; -> end; -> $$ Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; mysql> mysql> call testdata(); Query OK, 1 row affected (4 min 6.86 sec) mysql> mysql> insert into tb_innodb -> select * from tb_myisam; Query OK, 5000000 rows affected (1 min 31.47 sec) Records: 5000000 Duplicates: 0 Warnings: 0 mysql> mysql> select count(1) from tb_innodb; +----------+ | count(1) | +----------+ | 5000000 | +----------+ 1 row in set (7.75 sec) mysql> select count(id) from tb_innodb; +-----------+ | count(id) | +-----------+ | 5000000 | +-----------+ 1 row in set (7.17 sec) mysql> select count(name) from tb_innodb; +-------------+ | count(name) | +-------------+ | 5000000 | +-------------+ 1 row in set (6.22 sec) mysql> select count(*) from tb_innodb; +----------+ | count(*) | +----------+ | 5000000 | +----------+ 1 row in set (6.34 sec) mysql> mysql> select count(1) from tb_myisam; +----------+ | count(1) | +----------+ | 5000000 | +----------+ 1 row in set (0.00 sec) mysql> select count(id) from tb_myisam; +-----------+ | count(id) | +-----------+ | 5000000 | +-----------+ 1 row in set (0.00 sec) mysql> select count(name) from tb_myisam; +-------------+ | count(name) | +-------------+ | 5000000 | +-------------+ 1 row in set (1.24 sec) mysql> select count(*) from tb_myisam; +----------+ | count(*) | +----------+ | 5000000 | +----------+ 1 row in set (0.00 sec) mysql> mysql> truncate table tb_innodb; Query OK, 5000284 rows affected (0.08 sec) mysql> truncate table tb_myisam; Query OK, 0 rows affected (0.02 sec) mysql> 一个表 a 有 b,c,d,e,f 五个字段。两种方式进行查询。 ①select * from a ②select b,c,d,e,f from a 两者的执行速度。 当有大量记录的时候②的速度明显的快于① 当记录很少的时候①的速度快于② 因为查找的时候 都是从系统表里面在查找,a表的内容都是存在系统表里面的。 select * 会查询所有的系统表 当选择条件后,查找的系统表的数目会减少。 一个表 a 有 b,c,d,e,f 五个字段。两种方式进行查询。 SQL code ①select * from a ②select b,c,d,e,f from a 两者的执行速度。 当有大量记录的时候②的速度明显的快于① 当记录很少的时候①的速度快于② 因为查找的时候 都是从系统表里面在查找,a表的内容都是存在系统表里面的。 select * 会查询所有的…… 一般情况下,两着返回结果是一样的 假如表沒有主键(Primary key), 那么count(1)比count(*)快 如果有主键的話,那主键作为count的条件时候count(主键)最快 如果你的表只有一个字段的话那count(*)就是最快的 count(*) 跟 count(1) 的结果一样,都包括对NULL的统计 count(column) 是不包括NULL的统计 INNODB,MYSQL5.1.32,,10万条记录测试 SELECT SQL_NO_CACHE COUNT(XM) FROM JZG1;0.097 SELECT SQL_NO_CACHE COUNT(1) FROM JZG1;0.058 SELECT SQL_NO_CACHE COUNT(*) FROM JZG1;0.071 SELECT SQL_NO_CACHE COUNT(BH) FROM JZG1;0.085 在XM上建立有复合索引,BH上单独索引 myisam,MYSQL5.1.32,,10万条记录测试 在XM上建立有复合索引,BH上单独索引 SELECT SQL_NO_CACHE COUNT(XM) FROM JZG1;0.042 SELECT SQL_NO_CACHE COUNT(1) FROM JZG1;0.000 SELECT SQL_NO_CACHE COUNT(*) FROM JZG1;0.000 SELECT SQL_NO_CACHE COUNT(BH) FROM JZG1;0.036 在MYISAM引擎下,两者速度一致 在INNODB引擎下,COUNT(1)略快于COUNT(*)
mysql> select table_rows from information_schema.tables where table_name='t1';
+------------+
| table_rows |
+------------+
| 4 |
+------------+
1 row in set (0.00 sec)
来自 http://bbs.csdn.net/topics/370167999