为什么select count(*)在myisam比innodb里效率高,innodb里如何优化?

因为MySQL的MyISAM引擎在内部维护了一个计数器,当select count(*)其实就是拿到这个计数器的最新数值返回即可,而innodb却是要实时统计的。

那么,为什么innodb存储引擎不也维护一个计数器呢?

那是因为对于InnoDB这样的事务性存储引擎,存储准确的行数是不太现实的,因为多个事务可能同时发生,每个事务都有可能影响计数。 InnoDB不保留表中的行数,因为并发事务可能同时“看到”不同的行数。因此,SELECT COUNT(*)语句只计算当前事务可见的行。

为了处理SELECT COUNT(*)语句,InnoDB扫描表的索引,如果索引不是完全在缓冲池中,那么这将花费一些时间。

经过实践发现,不同的服务器配置下,当innodb表的行数达到数百万、数十万甚至数万的情况下,select count(*) 就会非常慢(需要十几秒甚至几分钟!),那么如何优化呢?

建议采用二级索引速度会比用主键索引更快。

在InnoDB引擎中,当我们通过二级索引统计数据的时候,无需扫描数据文件(二级索引存储指定字段的索引,实际的指向位置是主键索引。);而通过主键索引统计数据时,由于主键索引与数据文件存放在一起,所以每次都会扫描数据文件,所以主键索引统计没有二级索引效率高。

innodb表中除了主键ID之外,再找一个字段进行索引,然后在查询的时候使用select count(第二索引的字段),查询效率会大大提高。

0

堆表和索引组织表区别

堆表(heap table)数据插入时时存储位置是随机的,主要是数据库内部块的空闲情况决定,获取数据是按照命中率计算,全表扫表时不见得先插入的数据先查到。
索引表(iot)数据存储是把表按照索引的方式存储的,数据是有序的,数据的位置是预先定好的,与插入的顺序没有关系。
索引表的查询效率逼堆表高(相当于查询索引的效率),插入数据的速度比堆表慢。
索引表适用场景:
适用于信息检索、空间和OLAP程序。
1、 代码查找表。
2、 经常通过主码访问的表。
3、 构建自己的索引结构。
4、 加强数据的共同定位,要数据按特定顺序物理存储。
5、 经常用between…and…对主码或唯一码进行查询。数据物理上分类查询。如一张订单表,按日期装载数据,想查单个客户不同时期的订货和统计情况。

常用数据库支持情况:
Oracle支持堆表,也支持索引组织表
PostgreSQL只支持堆表,不支持索引组织表
Innodb只支持索引组织表

0