mysql count函数


我的数据库中2000W+ 条数据
在前台分页时 因为要查询出所有记录数。
select count(*) from customer; 平均70+秒
select count(1) from customer;平均也要70多秒
我想问下对这种大数据量的查询如何优化?

mysql 性能

cccp218 11 years, 8 months ago

我认为这个 快不了.

select count(*) from customer;
InnoDB每次都需要重新计算, 2kw+ 数据, 就算走覆盖索引也 需要时间.

如果对结果要求没那么精确, 可以考虑把 表记录 条数 放入缓存, 每次从缓存读就好. 程序 插入/删除 数据库记录的同时, 更新缓存.

要提到的一点就是, MyISAM 会把 表信息 存在磁盘里, 不需要每次计算, 所以MyISAM 计算表记录 条数 基本不需要时间.

最后说一下, 关于select count(*) from customer;
count(*) 在sql里有特殊含义, 就是 求结果集 记录数. 和count(0) 同义.
explain extended -> show warnings 可以看到, mysql这么处理:

   
  mysql> show warnings;
  
+-------+------+---------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------+
| Note | 1003 | select count(0) AS `count(*)` from `test1`.`tmp2` |
+-------+------+---------------------------------------------------+

更新

"我目前一个表中有2000W+ 数据 重创表到数据的插入 只有一个默认主键索引 primary;
这中情况下我在mysql 中count(*) 这个表 是需要花费平均60秒的时间;(当然这可能根据我的电脑配置有关)但是我在该表中的datetime 字段中添加一个index 索引,我在次count(*)这个表时只需要花费平均15秒的时间这是为什么? — Heu_"

   
  -- 这需要理解一下InnoDB的索引结构.
  
http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html
InnoDB是 Index Clustered Table, 主索引叶节点 存放 表记录; 所以 走主键索引 即是全表扫描(如有误请指出); 二级索引 相对来说会小一些, 所以走覆盖索引会 更快.
只有一个二级索引, 可以 查询 information_schema.tables 里的 DATA_LENGTH 和 INDEX_LENGTH 来查看 表数据大小 和 二级索引的大小, 后者应该会小很多.

"还有个问题是 InnoDB引擎和myasm 引擎的区别的 它们哪个更常用"

   
  -- 我记得 高性能mysql 里提过, MySql实际使用中, 90%多以上 是用的 InnoDB
 

洩矢緅访子 answered 11 years, 8 months ago

Your Answer