• 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)

  • 相关阅读:
    ios app 开发中ipa重新签名步骤介绍-备
    推荐IOS开发3个工具:Homebrew、TestFight、Crashlytics-b
    iOS开发工具——统计Crash的工具Crashlytics-备用
    摘要算法
    Xcode中将图片放入Images.xcassets和直接拖入的区别
    PHP面向对象的基本写法(区别于java)
    PHP 解决时差8小时的问题
    Java-Hirbernate小结大纲
    PHP替换数据库的换行符
    Java-strurs总结
  • 原文地址:https://www.cnblogs.com/katec/p/9259517.html
Copyright © 2020-2023  润新知