MYSQL count(*) 超慢,怎么破?

balance2014 发布于 2015/08/28 17:23
阅读 4K+
收藏 3
MYSQL count(*) 超慢,怎么破? 表数据100W 大小3G ,求大神
加载中
0
樂天
樂天

如果用到where,要命中索引,否则会扫全表导致速度很慢。如果没有where,可以在另一张table里维护这张表的数量。

关于索引:
理解MySQL——索引与优化
用好SELECT索引 提高MySQL查询统计速度

0
balance2014
balance2014

引用来自“樂天”的评论

如果用到where,要命中索引,否则会扫全表导致速度很慢。如果没有where,可以在另一张table里维护这张表的数量。

关于索引:
理解MySQL——索引与优化
用好SELECT索引 提高MySQL查询统计速度

感谢回复,现在count(*)无问题,但是带条件的select还是很慢
樂天
樂天
那就是没有用好索引了。
0
水牛叔叔
水牛叔叔
count(id)什么的,还加索引
0
balance2014
balance2014

引用来自“樂天”的评论

如果用到where,要命中索引,否则会扫全表导致速度很慢。如果没有where,可以在另一张table里维护这张表的数量。

关于索引:
理解MySQL——索引与优化
用好SELECT索引 提高MySQL查询统计速度

引用来自“balance2014”的评论

感谢回复,现在count(*)无问题,但是带条件的select还是很慢
绝大部分的字段都有可能作为查询条件,不可能所有字段全都加索引吧
0
张乐1024
张乐1024

一般我很少用count(*),而改用select count(1) from xxx;这个语法在表中列比较多的时候会感觉到明显的速度差异。

另外主要控制速度的原因还是在索引上,如果你表数据量很大,而且又没有索引肯定速度会很慢。如果你说绝大部分都有可能作为查询条件的话,可以考虑把可以过滤掉最多纪录的条件放在最先执行的位置。oracle的where条件是从右至左,也就是id = xxx应该放在最右边,其他数据库都是从左至右(貌似是这样),所以id = xxx应该放最左边。

还有如果可否考虑在使用未加索引的列过滤时,先用时间字段来过滤掉大部分数据?一般表里都有个时间字段,用时间区间先过滤掉大部分数据,这时候再用未加索引的列来过滤其他数据,大部分时间都会查询速度很快,除非你时间跨度比较长!!!

0
balance2014
balance2014

引用来自“张乐1024”的评论

一般我很少用count(*),而改用select count(1) from xxx;这个语法在表中列比较多的时候会感觉到明显的速度差异。

另外主要控制速度的原因还是在索引上,如果你表数据量很大,而且又没有索引肯定速度会很慢。如果你说绝大部分都有可能作为查询条件的话,可以考虑把可以过滤掉最多纪录的条件放在最先执行的位置。oracle的where条件是从右至左,也就是id = xxx应该放在最右边,其他数据库都是从左至右(貌似是这样),所以id = xxx应该放最左边。

还有如果可否考虑在使用未加索引的列过滤时,先用时间字段来过滤掉大部分数据?一般表里都有个时间字段,用时间区间先过滤掉大部分数据,这时候再用未加索引的列来过滤其他数据,大部分时间都会查询速度很快,除非你时间跨度比较长!!!

mysql的机制好像是这样的:从头至尾找数据,如果找到了就返回,例如你要搜索200条数据,mysql在找到了200条符合的后直接就返回了,所以找基数大的数据会快一点。但是在搜不存在或者基数很小的数据的时候就免不了全表扫描了,所以就很慢。所以过滤掉大部分数据的前提是把整张表全部扫一遍,但是3G多的数据量做一遍扫描确实太慢了。
张乐1024
张乐1024
回复 @balance2014 : 如果查询条件里面有索引的话就不会导致全表扫描了,因为索引已经帮你过滤掉那些不符合的记录了。所以我才推荐尽量使用索引过滤,如果实在需要用没有索引的字段来过滤的话,那么就可以考虑增加一个日期过滤,日期字段增加索引!!!
balance2014
balance2014
不知道理解的是否有误,望指正。^_^
0
zigzagroad
zigzagroad
如果所有的字段都会作为查询条件,那么还是遵从80-20原则吧,把最常用的加上索引以满足80%的查询需求。
返回顶部
顶部