首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
拉钩
V2EX  ›  MySQL

为什么统计查询这么慢

  •  
  •   lxy · 2016-03-17 17:37:23 +08:00 · 2503 次点击
    这是一个创建于 1000 天前的主题,其中的信息可能已经有所发展或是发生改变。
    mysql> select count(*) from threads;

    InnoDB ,大约 150 万数据,有主键,六个字段,用时 7s 。我觉得应该能在一秒内完成查询。这个查询会不会临时锁表?因为执行的同时还有另外三个连接在做其它的查询。还是因为阿里云 ECS 的磁盘 IO 太慢?
    20 回复  |  直到 2016-03-25 15:08:07 +08:00
        1
    aliipay   2016-03-17 19:58:05 +08:00
    查询语句?索引?啥都不说怎么看
        2
    wy315700   2016-03-17 20:02:36 +08:00
    不要用 count(*)
    不要用 count(*)
    不要用 count(*)
        3
    hxsf   2016-03-17 20:13:26 +08:00 via Android
    count(主键)
        4
    huiyue   2016-03-17 20:14:23 +08:00
    没有索引?用 count(id)
        5
    ipconfiger   2016-03-17 20:31:40 +08:00
    count 怎么都快不起来的, 特别是不加条件全表 count, 我说的 innodb
    要么就专门拿个表来做计数器
        6
    SparkMan   2016-03-17 20:50:40 +08:00
    innodb 的 count 需要全表扫描, myisam 直接读 count 值所以快,但是你有主键索引,不应该这么慢
        7
    ty0716   2016-03-17 20:53:17 +08:00 via iPhone
    count 主键 /索引看看,
    阿里云机械盘 io 不好出了名的,不知道是不是故意的为了推销 rds
        8
    devinww   2016-03-17 21:00:41 +08:00
    不要 count(*),count(1) 也好。
        9
    cyberdak   2016-03-17 21:12:46 +08:00
    为何楼上群众们的说法。。和我之前在高性能 mysql 上面看的完全冲突?

    书中是提倡使用 count(*)的
        10
    3dwelcome   2016-03-17 21:24:32 +08:00 via Android
    书上是 myisam 吧。
        11
    3dwelcome   2016-03-17 21:26:23 +08:00 via Android
    瓶颈在磁盘 io 可能性最大。
        12
    cyberdak   2016-03-17 21:40:02 +08:00
    myisam 就可以直接通过引擎的特性得到没有 where 条件的 count(*)结果了。。
        13
    yangqi   2016-03-17 21:46:41 +08:00
    innodb 就这样,每次查询行数都要经过以下步骤,肯定慢,不像 myisam 直接有行数值

    * ib_logfile0/ib_logfile1 (Redo Logs)
    * ibdata1
    ** Undo Logs
    ** Rollbacks
    ** Data Dictionary Changes
    * Buffer Pool Management
    * Transaction Isolation (4 types)
    ** Repeatable Reads
    ** Read Committed
    ** Read Uncommitted
    ** Serializable
        14
    allenhu   2016-03-18 08:32:37 +08:00 via Android
    时代不同了, count (*)没有问题
    如果可以,换 myisam 吧
        15
    cyberdak   2016-03-18 09:36:40 +08:00
    昨天等不到楼主
    也等不到楼上其他的回复

    然后就自己去插入了一份测试数据。。

    191w 表数据的 innodb,六个字段,一个自增 int id ,其他五个 varchar 200 ,然后当前时间填充,都是 not null

    实测就是不管 count(*),count(id),count(1) 的耗时都是一样的

    测试的环境是 mysql 5.5
        16
    lxy   2016-03-18 09:57:28 +08:00
    @cyberdak 其实我后来测试发现 count(*)多几次就快多了……反正也不是常用,耗时不是问题,只是有点好奇。
        17
    jhdxr   2016-03-18 15:44:53 +08:00
    @lxy 多几次就快了是有了查询缓存。。。
        18
    CosWind   2016-03-18 17:09:21 +08:00
    mysql 现在没那么傻了, count(*)对它来说最好优化
        19
    likuku   2016-03-25 14:53:53 +08:00
    让 InnoDB 的全表扫描快 10 倍 - 技术翻译 - 开源中国社区 :
    http://www.oschina.net/translate/making-full-table-scan-10x-faster-in-innodb?print
        20
    likuku   2016-03-25 15:08:07 +08:00
    2013 年 9 月,我自己在同一台机器(自有物理机) 上分次进行独占本地测试:
    count(*) 扫全表的话, postgresql 要比 InnoDB 快 7 倍。

    巴特, myisam 还是最快的。

    用的测试范例,很简单的表结构( 1841495 行),主键索引,日期有索引:

    InnoDB:
    mysql> select count(*) from status;
    +----------+
    | count(*) |
    +----------+
    | 1841495 |
    +----------+
    1 row in set (3.53 sec)

    MyISAM:
    mysql> select count(*) from status;
    +----------+
    | count(*) |
    +----------+
    | 1841495 |
    +----------+
    1 row in set (0.00 sec)

    PostgreSQL:
    postgres=# select count(*) from status;
    count
    ---------
    1841495
    (1 row)

    Time: 516.717 ms
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2224 人在线   最高记录 4019   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 20ms · UTC 15:08 · PVG 23:08 · LAX 07:08 · JFK 10:08
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1