伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

当在mysql5.7上发现这个bug,小心脏不好受了

来源:本站原创 浏览:113次 时间:2022-09-19

到底有多严重, 请看下面的测试结果:


    (这个bug的线索来源一个不曾相识的朋友,前段时间通过邮件向作者请教这个问题,因为太忙,没有顾上,当时也不以为然。今天抽时间来复核这个问题,结果大吃一惊。非常感谢这个朋友)。


       一个表,表结构如下:

CREATE TABLE "user_task" (

  "id" int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',

  "parent_id" int(10) NOT NULL DEFAULT '0' COMMENT '问题id',

  "author" int(10) NOT NULL DEFAULT '0' COMMENT '发布人pid',

  "con_id" int(10) NOT NULL COMMENT '群组id',

  "type" tinyint(2) NOT NULL DEFAULT '0' COMMENT '类型(0 问题;1回答)',

  "title" varchar(200) NOT NULL DEFAULT '' COMMENT '标题',

  "info" varchar(500) NOT NULL DEFAULT '' COMMENT '文本',

  "pic" text NOT NULL COMMENT '图片(json)',

  "audio" text NOT NULL COMMENT '音频(json)',

  "start_time" int(10) NOT NULL DEFAULT '0' COMMENT '发布时间',

  "end_time" int(10) NOT NULL DEFAULT '0' COMMENT '截止时间',

  "create_at" int(10) NOT NULL,

  "modify_at" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

  "isread" tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '0 已读 1 未读',

  PRIMARY KEY ("id"),

  UNIQUE KEY "idx_con_title" ("con_id","title")

) ENGINE=InnoDB AUTO_INCREMENT=401 DEFAULT CHARSET=utf8   


这个表一个主键+一个唯一性索引。数据量也很少。

mysql> select count(*) from user_task;

+----------+

| count(*) |

+----------+

|       54 |

+----------+

1 row in set (15.76 sec)

总共54条数据。


然后我们执行下面的这些sql , 请开始仔细观察。

mysql>  SELECT distinct  con_id   FROM user_task  where id in (56,57); 

+--------+

| con_id |

+--------+

|    844 |

+--------+

 

mysql> explain  SELECT distinct  con_id   FROM user_task  where id in (56,57); 

+----+-------------+-----------+------------+-------+-----------------------+---------+---------+------+------+----------+------------------------------+

| id | select_type | table     | partitions | type  | possible_keys         | key     | key_len | ref  | rows | filtered | Extra                        |

+----+-------------+-----------+------------+-------+-----------------------+---------+---------+------+------+----------+------------------------------+

|  1 | SIMPLE      | user_task | NULL       | range | PRIMARY,idx_con_title | PRIMARY | 4       | NULL |    2 |   100.00 | Using where; Using temporary |

+----+-------------+-----------+------------+-------+-----------------------+---------+---------+------+------+----------+------------------------------+

查看执行计划,走了主键索引。 


mysql>  SELECT distinct  con_id   FROM user_task  where id in (56,57,58);

+--------+

| con_id |

+--------+

|    844 |

|    785 |

+--------+

2 rows in set (17.30 sec)


mysql>  SELECT distinct  con_id   FROM user_task  where id in (56,57,58,66);

+--------+

| con_id |

+--------+

|    844 |

|    785 |

+--------+


mysql>  SELECT distinct  con_id   FROM user_task  where id in (56,57,58,66,70);

+--------+

| con_id |

+--------+

|    844 |

|    785 |

+--------+

2 rows in set (20.64 sec)


mysql>  SELECT distinct  con_id   FROM user_task  where id in (56,57,58,66,70,71);


Empty set (3 min 0.16 sec)

看到了没, 妖娥子在这里出现了,where 条件范围变大了, 结果却没有了,一身汗。。。。。


   结果为什么会变没有了? 谁吃了这个结果? 查看执行计划,

mysql> explain   SELECT distinct  con_id   FROM user_task  where id in (56,57,58,66,70,71);

+----+-------------+-----------+------------+-------+-----------------------+---------------+---------+------+------+----------+---------------------------------------+

| id | select_type | table     | partitions | type  | possible_keys         | key           | key_len | ref  | rows | filtered | Extra                                 |

+----+-------------+-----------+------------+-------+-----------------------+---------------+---------+------+------+----------+---------------------------------------+

|  1 | SIMPLE      | user_task | NULL       | range | PRIMARY,idx_con_title | idx_con_title | 4       | NULL |    6 |    11.11 | Using where; Using index for group-by |

+----+-------------+-----------+------------+-------+-----------------------+---------------+---------+------+------+----------+---------------------------------------+

1 row in set, 1 warning (0.00 sec)


发现走的是idx_con_title  索引 。   


        鄙视mysql:   走这个索引也无伤大雅, 干嘛把结果弄丢了?



如果改写成group by , 如下

SELECT  con_id  ,count(*)  FROM user_task  where id in (56,57,58,66,70,71) group by con_id ; 


结果正常。


 如果将索引idx_con_title 删除, 下面sql结果正常。

 SELECT distinct  con_id   FROM user_task  where id in (56,57,58,66,70,71);


          巨坑巨坑的bug,,,,,,且在5.7.18 以及5.7.20上均出现,其他版本未测试。


       目前怀疑: 问题出现mysql的优化器上面,使用另外一个索引时,执行路径不完整(错误)导致 。明天向官方提bug.  



  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net