关于mysql innodb count(*)速度慢的解决办法

innodb引擎在统计方面和myisam是不同的,Myisam内置了一个计数器,所以在使用 select count(*) from table 的时候,直接可以从计数器中取出数据。而innodb必须全表扫描一次方能得到总的数量。要初步解决这个问题,需要做不同于myisam的一些工作:

1、使用第二索引(一般不使用主键索引),并且添加where条件,如:



代码如下:

select count(*) from product where comp_id>=0 ;
show index from product ;
id primary key
comp_id index

2、如果只需要粗略统计的话也可使用

show status from product; 来得到大约值
这种方法可在数据分页中使用!

3、使用外部计数器,比如建立一个触发器来计数或者在程序上使用缓存方式定时计数,缺陷是这些方法会额外消耗一些资源!

参考资料:

mysql高性能:http://www.mysqlperformanceblog.com/2006/12/01/count-for-innodb-tables/
mysql DBA:http://imysql.cn/2008_06_24_speedup_innodb_count

COUNT(*) for Innodb Tables

I guess note number one about MyISAM to Innodb migration is warning what Innodb is very slow in COUNT(*) queries. The part which I often however see omitted is fact it only applies to COUNT(*) queries without WHERE clause.
So if you have query like SELECT COUNT(*) FROM USER It will be much faster for MyISAM (MEMORY and some others) tables because they would simply read number of rows in the table from stored value. Innodb will however need to perform full table scan or full index scan because it does not have such counter, it also can't be solved by simple singe counter for Innodb tables as different transactions may see different number of rows in the table.
If you have query like SELECT COUNT(*) FROM IMAGE WHERE USER_ID=5 this query will be executed same way both for MyISAM and Innodb tables by performing index rage scan. This can be faster or slower both for MyISAM and Innodb depending on various conditions.
In real applications there are much more queries of second type rather than first type so it is typically not as bad problem as it may look. Most typically count of rows is needed by admin tools which may show it in table statistics, it may also be used in application stats to show something like “We have 123.345 users which have uploaded 1.344.656 images” but these are normally easy to remove.
So remember Innodb is not slow for ALL COUNT(*) queries but only for very specific case of COUNT(*) query without WHERE clause. It does not mean I would not like to see it fixed though, it is pretty annoying.

转自:http://www.sphinxsearch.org/archives/89

(0)

相关推荐

  • 有关mysql中ROW_COUNT()的小例子

    注:mysql中的ROW_COUNT()可以返回前一个SQL进行UPDATE,DELETE,INSERT操作所影响的行数. MySQL上的测试(数据库版本为:5.1.22): 1.创建数据库表: 复制代码 代码如下: create table t(  id int,  name varchar(50),  address varchar(100),  primary key(id,name)  )engine =InnoDB; 2.插入测试数据: 复制代码 代码如下: insert into t

  • mysql count详解及函数实例代码

    mysql count详解 count函数是用来统计表中或数组中记录的一个函数,下面我来介绍在mysql中count函数用法. count(*) 它返回检索行的数目, 不论其是否包含 NULL值. SELECT 从一个表中检索,而不检索其它的列,并且没有 WHERE子句时, COUNT(*)被优化到最快的返回速度. 例如: mysql> SELECT COUNT(*) FROM student; COUNT(DISTINCT 字段)这个优化仅适用于 MyISAM表, 原因是这些表类型会储存一个函

  • mysql技巧之select count的区别分析

    1.测试环境 OS:LinuxDB:mysql-5.5.18table:innodb存储引擎 表定义如下: 2. 测试场景与分析[统计表group_message的记录数目] (1)select count(*)方式 (2)select count(1)方式 (3)select count(col_name)方式 分别使用 select count(group_id) select count(user_id) select count(col_null) 通过上述测试结果可以看到,select

  • Mysql中的count()与sum()区别详细介绍

    首先创建个表说明问题 复制代码 代码如下: CREATE TABLE `result` ( `name` varchar(20) default NULL, `subject` varchar(20) default NULL, `score` tinyint(4) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 插入一些数据, 复制代码 代码如下: insert into result values ('张三','数学',90), ('张三'

  • mySQL count多个表的数据实例详解

    一.实现需求 最近在做成就系统,成就中有很多维度都和数量有关,比如用户粉丝数达到多少50个,授予 名扬四海 称号,用户点赞达到 100 次,授予 点赞圣手 称号等等. 粉丝数在 user_relation 表 点赞数在 user_praise 表 按照以往的做法,如果需要查询用户的这些数据,又因为数据是在不同的表中,所以往往会分开多条 SQL 查询,比如: SELECT count(*) mysh FROM user_relation WHERE other_uid =123456; SELEC

  • MySQL里的found_row()与row_count()的解释及用法

    出处:mysqlpub.com MySQL中有两个函数来计算上一条语句影响了多少行,不同于SqlServer/Oracle,不要因为此方面的差异而引起功能问题: 1,判断Select得到的行数用found_rows()函数进行判断. 2,判断Update或Delete影响的行数用row_count()函数进行判断,这里需要注意,如果Update前后的值一样,row_count则为0,而不像SqlServer里的@@rowcount或Oracle里的rowcount,只要update到行,影响的行

  • 浅析一个MYSQL语法(在查询中使用count)的兼容性问题

    简单来说就是在查询中使用count以及更多字段 复制代码 代码如下: select count(id),id,name from table 很尴尬的,我的环境是5.5的,这个是能获取到结果的,但是运行到服务器就不行了好吧,报了一个错误 复制代码 代码如下: #1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY claus

  • mysql_num_rows VS COUNT 效率问题分析

    mysql_num_rows 和 count( * ) 都能统计总数,那个能好一点呢? 或者 分别什么时候用num_rows 和 count( * )呢 一个直观的对比 测试数据: 条数:139764条 数据表大小:500M 结果: fetch_num_rows 用时:35.272329092026 count(*) 用时:0.071956872940063 如果单纯统计数量 当然是count(*) fetch_num_rows必须遍历数据库以后才能得出 效率低于count(*)

  • MySQL中distinct和count(*)的使用方法比较

    首先对于MySQL的DISTINCT的关键字的一些用法: 1.在count 不重复的记录的时候能用到,比如SELECT COUNT( DISTINCT id ) FROM tablename:就是计算talbebname表中id不同的记录有多少条. 2,在需要返回记录不同的id的具体值的时候可以用,比如SELECT DISTINCT id FROM tablename:返回talbebname表中不同的id的具体的值. 3.上面的情况2对于需要返回mysql表中2列以上的结果时会有歧义,比如SE

  • 详细解读MySQL中COUNT函数的用法

    MySQL的COUNT函数是最简单的功能,非常有用的计算,预计由一个SELECT语句返回的记录数. 要了解COUNT函数考虑的EMPLOYEE_TBL的的表具有以下记录: mysql> SELECT * FROM employee_tbl; +------+------+------------+--------------------+ | id | name | work_date | daily_typing_pages | +------+------+------------+----

  • 关于mysql中innodb的count优化问题分享

    一般采用二级索引去count:比如:id 是pk aid是secondary index 采用 复制代码 代码如下: select count(*) from table where id >=0;或select count(*) from table; 效果是一样的,都是默认使用pk索引,且都要全表扫描,虽然第一种性能可能高一些,但是没有明显区别. 但是如果用secondary index 复制代码 代码如下: select count(*) from table where aid>=0;

  • MYSQL中统计查询结果总行数的便捷方法省去count(*)

    MYSQL的关键词 : SQL_CALC_FOUND_ROWS 查看手册后发现此关键词的作用是在查询时统计满足过滤条件后的结果的总数(不受 Limit 的限制) 例如: 复制代码 代码如下: SELECT SQL_CALC_FOUND_ROWS tid FROM cdb_threads WHERE fid=14 LIMIT 1,10; 假设满足条件的有1000条,这里返回10条. 立即使用 复制代码 代码如下: SELECT found_rows() AS rowcount; 则返回的 rowc

随机推荐