MySQL查询耗时过长问题

zmx198768 2010-04-20 03:20:57
一、表基本信息如下



无任何外键及索引


二、 查询执行时间问题
1. 执行语句 SELECT Count(MESSAGE_ID) FROM blog_message 耗时9.484s, 记录结果为 180525条记录
2. 执行语句查询最后一条记录 SELECT * FROM blog_message WHERE MESSAGE_ID='1000224687' 耗时0.031s
3. 执行语句查询第一条记录 SELECT * FROM blog_message WHERE MESSAGE_ID='1000000000' 耗时不到 0.000s
4. 执行语句查询中间记录 SELECT * FROM blog_message WHERE MESSAGE_ID='1000116878' 耗时0.031s


问题,总共的数据也才十八万条而已,为什么count的时候耗时将近十秒,而如果在navicat中直接查询表信息的话一下子就可以统计出来总共有多少条记录了。
求原因及改进方案




刚才重新执行了一下,正常情况下查询速度大概是11秒。
执行了一次analyze,速度提升到9秒多。
再执行了一次优化,报告无法优化,自动改成 analyze+recreate ,速度提升到8秒左右



...全文
876 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zmx198768 2010-04-20
  • 打赏
  • 举报
回复
另外建立了一个索引
执行语句
EXPLAIN SELECT count(message_id) FROM blog_message WHERE blog_id !='';
耗时0.25S
iihero_ 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zmx198768 的回复:]

我现在想做的是查询blog_message这张表里面的记录总数,有没有简便的方法可以快速实现?
[/Quote]

有倒是有,不过,走的是旁道。针对 该表写两个触发器,insert, delete,
每insert一次,在另一个表sum里头,加1,delete一次,减1
这样,每次你直接从sum里头取值就完了。
WWWWA 2010-04-20
  • 打赏
  • 举报
回复
我现在想做的是查询blog_message这张表里面的记录总数,有没有简便的方法可以快速实现?

一般而言,
SELECT Count(MESSAGE_ID) FROM blog_message
是简便的方法
zmx198768 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 iihero 的回复:]
引用 4 楼 acmain_chm 的回复:

主键会自动创建索引的,所以这张表上MESSAGE_ID做为主键,MYSQL已经创建了这个字段的唯一索引。

SELECT Count(MESSAGE_ID) FROM blog_message 是全表/全索引遍历。 所以会花时间比较长。

navicat中直接查询表信息的话一下子就可以统计出来总共有多少条记录了。
这个是通过 infor……
[/Quote]

呃,我的意思是,我没有自动手段去创建索引和外键。。。
zmx198768 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 acmain_chm 的回复:]
主键会自动创建索引的,所以这张表上MESSAGE_ID做为主键,MYSQL已经创建了这个字段的唯一索引。

SELECT Count(MESSAGE_ID) FROM blog_message 是全表/全索引遍历。 所以会花时间比较长。

navicat中直接查询表信息的话一下子就可以统计出来总共有多少条记录了。
这个是通过 information_schema.tables 中的记录……
[/Quote]

我现在想做的是查询blog_message这张表里面的记录总数,有没有简便的方法可以快速实现?
iihero_ 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 acmain_chm 的回复:]

主键会自动创建索引的,所以这张表上MESSAGE_ID做为主键,MYSQL已经创建了这个字段的唯一索引。

SELECT Count(MESSAGE_ID) FROM blog_message 是全表/全索引遍历。 所以会花时间比较长。

navicat中直接查询表信息的话一下子就可以统计出来总共有多少条记录了。
这个是通过 information_schema.tables 中的……
[/Quote]

差点被楼主忽悠了,有个主键在那儿。呵呵。
ACMAIN_CHM 2010-04-20
  • 打赏
  • 举报
回复
主键会自动创建索引的,所以这张表上MESSAGE_ID做为主键,MYSQL已经创建了这个字段的唯一索引。

SELECT Count(MESSAGE_ID) FROM blog_message 是全表/全索引遍历。 所以会花时间比较长。

navicat中直接查询表信息的话一下子就可以统计出来总共有多少条记录了。
这个是通过 information_schema.tables 中的记录得到的信息,并不一定准确,你可以直接 select * from information_schema.tables 也会很快得到相关信息。
iihero_ 2010-04-20
  • 打赏
  • 举报
回复
你不建索引,想优化,实在看不出有什么意义。
zmx198768 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 iihero 的回复:]
count(*)意味着,要不就扫描全表,要不就扫描全索引,都是耗时的事情。因为你没带任何条件。只能系统自己判断哪种扫描稍快一点了。
相反,只根据index条件获取符合条件的记录,只需要通过索引快速定位记录,反而很快。道理就是这样子。
[/Quote]

我耗时长的查询是根据主键查询的,而不是count(*)

另外,这张表我没有任何索引
iihero_ 2010-04-20
  • 打赏
  • 举报
回复
count(*)意味着,要不就扫描全表,要不就扫描全索引,都是耗时的事情。因为你没带任何条件。只能系统自己判断哪种扫描稍快一点了。
相反,只根据index条件获取符合条件的记录,只需要通过索引快速定位记录,反而很快。道理就是这样子。

56,678

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧