mysql 之limit 的时候sending data 过长

这几天使用lucene在索引数据库记录,数据库里有1w左右的记录,其中最长的content字段,为text,当从数据库里通过分页查数据的时候使用一下语句

select * from article limit   ?,?

当limit 3000,60 开始 数据基本要3s的样子,当到8000的时候,真的有蛮慢,有时候要37s,通过mysql的性能分析得知mysql的主要时间都花在sending data上了

超过3000就会这样,使用索引第一次也会这样,当加大缓存时候第二次使用相同的查询会很快,不过随便改个条件就又很慢了。

当换一个策略,select * from article where id > 3000 limit 1,60 又非常快,

如果这样

SELECT * from article t ORDER BY t.id LIMIT 7000,60

用explain是使用索引的,但从上面可以得出,这条语句只有在排序那使用索引,也就是说,查询实际上 还是全表扫描。

那这样,换一种方式:select t.id from article  t.id limit 7000,60

然后 select t.* from article t where t.id in (...) 这些id中,然后用explain

1 SIMPLE t const PRIMARY PRIMARY4 const1

Primary说明使用了索引,这样就很快了

这里介绍一下mysql的profile性能分析

打开profile:

set profiling =1

可以查询最近执行的sql语句:

show profiles

根据queryid 查看具体的query

show profile for query 124

Sending data is not Sending data

05-11

rn[code=SQL]rnmysql> SHOW PROFILES;rn+----------+------------+------------------------------------------------------------------------------------------------------------------------------+rn| Query_ID | Duration | Query |rn+----------+------------+------------------------------------------------------------------------------------------------------------------------------+rn| 5 | 0.98439500 | SELECT DISTINCT smw_namespace, smw_title, smw_iw FROM `smw_rels2`,`smw_ids` WHERE p_id='8979' AND o_id=smw_id LIMIT 1000 |rn| 6 | 0.23709100 | SELECT smw_namespace, smw_title, smw_iw FROM `smw_rels2`,`smw_ids` WHERE p_id='8979' AND o_id=smw_id LIMIT 1000 |rn+----------+------------+------------------------------------------------------------------------------------------------------------------------------+rn6 rows in set (0.00 sec)rn rnmysql> SHOW PROFILE FOR QUERY 6;rn+--------------------------------+----------+rn| Status | Duration |rn+--------------------------------+----------+rn| starting | 0.000013 |rn| checking query cache for query | 0.000056 |rn| Opening tables | 0.000028 |rn| System lock | 0.000017 |rn| Table lock | 0.000047 |rn| init | 0.000017 |rn| optimizing | 0.000018 |rn| statistics | 0.000261 |rn| preparing | 0.000014 |rn| executing | 0.000002 |rn| [color=#FF0000]Sending data | 0.236548 [/color]|rn| end | 0.000008 |rn| query end | 0.000004 |rn| freeing items | 0.000040 |rn| storing result in query cache | 0.000012 |rn| logging slow query | 0.000002 |rn| cleaning up | 0.000004 |rn+--------------------------------+----------+rn17 rows in set (0.00 sec)rn rnmysql> SHOW PROFILE FOR QUERY 5;rn+--------------------------------+----------+rn| Status | Duration |rn+--------------------------------+----------+rn| starting | 0.000012 |rn| checking query cache for query | 0.000061 |rn| Opening tables | 0.000020 |rn| System lock | 0.000015 |rn| Table lock | 0.000045 |rn| init | 0.000016 |rn| optimizing | 0.000014 |rn| statistics | 0.000229 |rn| preparing | 0.000013 |rn| Creating tmp table | 0.000038 |rn| executing | 0.000003 |rn| Copying to tmp table | 0.983473 |rn| [color=#FF0000]Sending data | 0.000351[/color] |rn| end | 0.000004 |rn| removing tmp table | 0.000048 |rn| end | 0.000004 |rn| query end | 0.000004 |rn| freeing items | 0.000025 |rn| storing result in query cache | 0.000012 |rn| logging slow query | 0.000001 |rn| cleaning up | 0.000007 |rn+--------------------------------+----------+rn21 rows in set (0.00 sec)rn rn[/code]rn第5,6条,只有一个DISTINCT不一样。5用到了临时表进行数据去重。rn获取的数据都是一样的,SENDING DATA如果是发送数据到客户端这样话,就没办法解释为什么5,6的SENDING DATA时间相差这么巨大。rnrn往上再看一布操作耗时比较长的过程都是在executing后面。rn看到一个外国人问的这个问题,他说SENDING DATA后面的时间其实是executing的。rnrn从上面看来,没个参数项后面的值,代表的是此参数项前面那个参数项的执行时间,这样理解才说得通。rnrn请斑竹指正。rn

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试