为什么统计查询这么慢

2016-03-17 17:37:23 +08:00
 lxy
mysql> select count(*) from threads;

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

书中是提倡使用 count(*)的
3dwelcome
2016-03-17 21:24:32 +08:00
书上是 myisam 吧。
3dwelcome
2016-03-17 21:26:23 +08:00
瓶颈在磁盘 io 可能性最大。
cyberdak
2016-03-17 21:40:02 +08:00
myisam 就可以直接通过引擎的特性得到没有 where 条件的 count(*)结果了。。
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
allenhu
2016-03-18 08:32:37 +08:00
时代不同了, count (*)没有问题
如果可以,换 myisam 吧
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
lxy
2016-03-18 09:57:28 +08:00
@cyberdak 其实我后来测试发现 count(*)多几次就快多了……反正也不是常用,耗时不是问题,只是有点好奇。
jhdxr
2016-03-18 15:44:53 +08:00
@lxy 多几次就快了是有了查询缓存。。。
CosWind
2016-03-18 17:09:21 +08:00
mysql 现在没那么傻了, count(*)对它来说最好优化
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
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/264252

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX