mysql count 加速_MySQL超大表如何提高count速度

经常用到count统计记录数,表又超级大,这时候sql执行很慢,就是走索引,也是很慢的,怎么办呢?

1.这个时候我们就要想为什么这么慢:根本原因是访问的数据量太大,就算只计算记录数也是很慢的。

2.如何解决?减少数据访问量。

3.怎么才能减少访问量呢?更小的索引。

4.怎么能使索引更小呢?创建前缀索引。

至此我们的方案出来了!下面看看具体的:

表结构:

CREATE TABLE `sbtest3` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`k` int(11) NOT NULL DEFAULT '0',

`c` char(120) NOT NULL DEFAULT '',

`pad` char(60) NOT NULL DEFAULT '',

PRIMARY KEY (`id`),

KEY `k_3` (`k`)

) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1;

执行count花费3.58秒,不能接受!!!!!!

select count(*) from sbtest3;

+----------+

| count(*) |

+----------+

| 5000000 |

+----------+

1 row in set (3.58 sec)

看看执行计划,走的是k_3索引。

explain select count(*) from sbtest3;

+----+-------------+---------+-------+---------------+------+---------+------+---------+-------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+---------+-------+---------------+------+---------+------+---------+-------------+

| 1 | SIMPLE | sbtest3 | index | NULL | k_3 | 4 | NULL | 4804854 | Using index |

+----+-------------+---------+-------+---------------+------+---------+------+---------+-------------+

创建一个短索引。

create index idx_sbt3_c on sbtest3(c(1));

看执行计划选择了这个短索引。

explain select count(*) from sbtest3;

+----+-------------+---------+-------+---------------+------------+---------+------+---------+-------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+---------+-------+---------------+------------+---------+------+---------+-------------+

| 1 | SIMPLE | sbtest3 | index | NULL | idx_sbt3_c | 1 | NULL | 4804854 | Using index |

+----+-------------+---------+-------+---------------+------------+---------+------+---------+-------------+

执行一下sql花费0.59秒,还能接受。

select count(*) from sbtest3;

+----------+

| count(*) |

+----------+

| 5000000 |

+----------+

1 row in set (0.59 sec)

现实环境如果带where条件怎么办?

如下我想获得id>10000的记录数,花费2.55秒,不可接受!!!!

select count(*) from sbtest3 where id>10000;

+----------+

| count(*) |

+----------+

| 4990000 |

+----------+

1 row in set (2.55 sec)

可以换种思路:

先得到相反条件过滤数据多的记录数,然后再获得总数,然后相减,速度也是有很大的提高。

select count(*) from sbtest3 where id<=10000;

+----------+

| count(*) |

+----------+

| 10000 |

+----------+

1 row in set (0.08 sec)

select count(*) from sbtest3;

+----------+

| count(*) |

+----------+

| 5000000 |

+----------+

1 row in set (0.59 sec)

select 5000000 - 10000;

+----------------+

| 5000000 - 9999 |

+----------------+

| 49900010|

+----------------+

1 row in set (0.00 sec)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值