楼主: wanan_YLF

很奇怪的问题,explain 和 slowquery,谁在撒谎?

[复制链接]
论坛徽章:
4
ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222011新春纪念徽章
日期:2011-02-18 11:43:34ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:29
11#
发表于 2011-3-17 18:24 | 只看该作者
5.0下也有类似的问题

使用道具 举报

回复
论坛徽章:
138
19周年集字徽章-19
日期:2020-06-08 08:30:56马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02路虎
日期:2013-11-22 12:26:18问答徽章
日期:2014-05-08 12:15:31
12#
发表于 2011-3-17 19:09 | 只看该作者

回复 #10 wanan_YLF 的帖子

我不知道这个是不是mysql的bug,你这个sql条件和order by的字段是一致的,所以只要走索引都是不需要排序的,不管是走index full scan 和index range scan都是不需要做排序的,正常应该是先定位出MeiShiID的条件,然后根据limit再去做stopkey,这样不应该做index full scan就不会有你那的问题了


explain select MeiShiID from fc_meishi_old where MeiShiID>12586 order by MeiShiID ASC LIMIT 0,1;


看看这个的执行计划

如果你的MeiShiID是连续的数字,建议你直接根据MeiShiID的值和后面的Limit来算出MeiShiID的上边界,语句转换成

explain select MeiShiID from fc_meishi_old where MeiShiID>12586 and MeiShID<=计算出来的值

[ 本帖最后由 棉花糖ONE 于 2011-3-17 19:13 编辑 ]

使用道具 举报

回复
论坛徽章:
8
双黄蛋
日期:2011-08-11 14:51:29蜘蛛蛋
日期:2011-08-15 20:53:08灰彻蛋
日期:2011-08-23 17:46:31ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:56咸鸭蛋
日期:2012-01-09 11:14:00紫蛋头
日期:2012-03-20 17:08:01优秀写手
日期:2013-12-18 09:29:14
13#
 楼主| 发表于 2011-3-18 10:36 | 只看该作者

回复 #12 棉花糖ONE 的帖子

mysql> explain select MeiShiID from fc_meishi_old where MeiShiID>12586 order by MeiShiID ASC LIMIT 0,1;

+----+-------------+---------------+-------+---------------+---------+---------+------+-------+--------------------------+
| id | select_type | table         | type  | possible_keys | key     | key_len | ref  | rows  | Extra                    |
+----+-------------+---------------+-------+---------------+---------+---------+------+-------+--------------------------+
|  1 | SIMPLE      | fc_meishi_old | range | PRIMARY       | PRIMARY | 4       | NULL | 68904 | Using where; Using index |
+----+-------------+---------------+-------+---------------+---------+---------+------+-------+--------------------------+


我发现只要是order by ID (ID是主键)的这种情况下,查询都会很慢。。。

[ 本帖最后由 wanan_YLF 于 2011-3-18 10:41 编辑 ]

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
14#
发表于 2011-3-18 11:03 | 只看该作者

回复 #13 wanan_YLF 的帖子

我发现只要是order by ID (ID是主键) 你要是ORDER BY 为主键,而WHERE部分不包含主键,很容易误走主键先排序

这是优化器的缺陷.....

但是你的这个SQL不一样,WHERE与ORDER BY部分为同一个字段,且是主键的一部分,还是自增字段,按优化器优先是选择 WHERE部分走,再加上LIMIT 1很容易拿到值


还有一个担心就是,你InnoDB引擎的表,可能出现统计信息不准确导致的,这个跑久了的系统,容易偶尔出现此问题

使用道具 举报

回复
论坛徽章:
8
双黄蛋
日期:2011-08-11 14:51:29蜘蛛蛋
日期:2011-08-15 20:53:08灰彻蛋
日期:2011-08-23 17:46:31ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:56咸鸭蛋
日期:2012-01-09 11:14:00紫蛋头
日期:2012-03-20 17:08:01优秀写手
日期:2013-12-18 09:29:14
15#
 楼主| 发表于 2011-3-18 11:20 | 只看该作者

回复 #14 jinguanding 的帖子

不好意思,忘了说,这个是MyISAM 引擎的表。我也觉得我这个SQL很诡异啊。

你要是ORDER BY 为主键,而WHERE部分不包含主键,很容易误走主键先排序    举下面的例子

SELECT * FROM TABLEA  WHERE catid IN (15,16,17,18,19,20) ORDER BY id DESC LIMIT 8

即使有复合索引catid(catid,id),引擎也是使用主键索引。
explain的结果是:type 是index  ,extra是using where

强制使用catid索引。
explain的结果是:type 是range  ,extra是using where,using filesort

即使使用复合索引,也只是使用了第一个字段。真不知道mysql为什么死命这样!


我只能修改为
SELECT * FROM TABLEA  WHERE  id  in  (SELECT id FROM TABLEA   WHERE  catid  IN (15,16,17,18,19,20))  order by  id  limit 8 ;

不知除此之外还有什么办法。
因为这个语句是为了得到最新的8条记录,只有通过自增id来得到

[ 本帖最后由 wanan_YLF 于 2011-3-18 11:24 编辑 ]

使用道具 举报

回复
论坛徽章:
138
19周年集字徽章-19
日期:2020-06-08 08:30:56马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:02路虎
日期:2013-11-22 12:26:18问答徽章
日期:2014-05-08 12:15:31
16#
发表于 2011-3-18 11:30 | 只看该作者
SELECT * FROM TABLEA  WHERE  id  in  (SELECT id FROM TABLEA   WHERE  catid  IN (15,16,17,18,19,20))  order by  id  limit 8 ;

select * from A where id in (
select id tableA where catid=15 order by id limit 8
union all
select id tableA where catid=16 order by id limit 8
....
)  order by id limit 8

使用道具 举报

回复
论坛徽章:
8
双黄蛋
日期:2011-08-11 14:51:29蜘蛛蛋
日期:2011-08-15 20:53:08灰彻蛋
日期:2011-08-23 17:46:31ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:56咸鸭蛋
日期:2012-01-09 11:14:00紫蛋头
日期:2012-03-20 17:08:01优秀写手
日期:2013-12-18 09:29:14
17#
 楼主| 发表于 2011-3-18 11:35 | 只看该作者

回复 #16 棉花糖ONE 的帖子

这个我也想过,但15,16,17,18,19,20是另外一个查询的结果,通过程序赋值进来的,遇到几十个数字的话,那就比较复杂了。

也想过新增一列可以起到ID作用的列。

而且有一点很奇怪,对于子查询,引擎选择使用的索引也是主键。该表有41万的数据。catid in (15,16,17,18,19,20)的结果是4514个。

mysql> explain SELECT *  TABLEA  WHERE  id  in  (SELECT id FROM   TABLEA  WHERE  catid  IN (15,16,17,18,19,20))  order by  id  limit 8 ;
+----+--------------------+--------+-----------------+--------------------------------+---------+---------+------+------+-------------+
| id | select_type        | table  | type            | possible_keys                  | key     | key_len | ref  | rows | Extra       |
+----+--------------------+--------+-----------------+--------------------------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | TABLEA | index           | NULL                           | PRIMARY | 3       | NULL |    8 | Using where |
|  2 | DEPENDENT SUBQUERY | TABLEA | unique_subquery | PRIMARY,listorder,catid,catid2 | PRIMARY | 3       | func |    1 | Using where |
+----+--------------------+--------+-----------------+--------------------------------+---------+---------+------+------+-------------+

这个子查询的rows最近搞得我是真不敢相信了。
我的疑惑是,子查询走主键索引真的比较快吗?还是又是引擎的错误判断。

[ 本帖最后由 wanan_YLF 于 2011-3-18 11:48 编辑 ]

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
18#
发表于 2011-3-18 13:10 | 只看该作者

回复 #17 wanan_YLF 的帖子

这种情况不是误判,而是算法限制....

使用道具 举报

回复
论坛徽章:
8
双黄蛋
日期:2011-08-11 14:51:29蜘蛛蛋
日期:2011-08-15 20:53:08灰彻蛋
日期:2011-08-23 17:46:31ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:56咸鸭蛋
日期:2012-01-09 11:14:00紫蛋头
日期:2012-03-20 17:08:01优秀写手
日期:2013-12-18 09:29:14
19#
 楼主| 发表于 2011-3-18 13:16 | 只看该作者

回复 #18 jinguanding 的帖子

算法限制?怎么说?

使用道具 举报

回复
论坛徽章:
8
双黄蛋
日期:2011-08-11 14:51:29蜘蛛蛋
日期:2011-08-15 20:53:08灰彻蛋
日期:2011-08-23 17:46:31ITPUB十周年纪念徽章
日期:2011-11-01 16:26:292012新春纪念徽章
日期:2012-01-04 11:57:56咸鸭蛋
日期:2012-01-09 11:14:00紫蛋头
日期:2012-03-20 17:08:01优秀写手
日期:2013-12-18 09:29:14
20#
 楼主| 发表于 2011-3-18 14:10 | 只看该作者

回复 #18 jinguanding 的帖子

了解了一下你们的水平和工作,真的是佩服你们,年复一年地坚持在这里,耐心得回答一些菜鸟问题。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表