`
丁林.tb
  • 浏览: 792560 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

MySQL源码学习:关于整型判断的一个bug

阅读更多


问题 :

      这个 bug 来源于官方的一个 bug 报告 , 感谢 @ 印风 _ 小希 . 现象很容易描述 , 直接上例子 .  5.1 以后的版本都有此问题 .

CREATE TABLE `tb` (

  `a` int(11) DEFAULT NULL,

  `b` int(11) DEFAULT NULL,

  KEY `a` (`a`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into tb values (1,2),(2,5),(3,8),(4,6);

select * from tb force index (a) where a >=0.5;

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

| a    | b    |

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

|    2 |    5 |

|    3 |    8 |

|    4 |    6 |

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

4 rows in set (0.00 sec)


(1,2) 这个记录没有返回 .

说明一下 ,select 语句中用 force index 是以防全表扫描 . ( 不走索引 a 就正常了 ).


原因分析 :

MySQL 使用索引时 , 调用 innoDB index_read 接口 , 需要传入三个信息 : 查找的值 \ 索引 \ 查找方向 , 由于查询条件是 >=, 因此查询方向可选的是 HA_READ_AFTER_KEY HA_READ_KEY_OR_NEXT, 分别对应 > >=.

但是传入之前还要作查询优化 .

在这个例子中的流程 :

1)     MySQL 决定使用索引 a , 根据输入的值 (0.5), 取索引 [1, MAX). 之所以取 1, 是因为 a 是一个 int 类型 .;

2)     判断 0.5 1 的大小 , 0.5<1, 因此设置 tree->min_flag= NEAR_MIN; 表示实际要查找的值 , 小于传入索引范围的最小值 . 因此决定了使用 HA_READ_AFTER_KEY, 也就是 >0.5, 这没问题 .

3)     不幸的是 , 由于字段 a 是整型 , 真正传入的是 1, 逻辑变成 >1.

 

所以查找时 a=1 这个记录被忽略了 .

 

简单修改 :

      5.0 版本没这个问题 , 那时候没有 HA_READ_AFTER_KEY HA_READ_KEY_OR_NEXT 这些东西 .

      这两个值的差别只是在 innoDB 内部查找的时候要不要判断相等的那个值 , 简单的修改可以都处理为 HA_READ_KEY_OR_NEXT. 不用担心 MySQL > 变成 >= 以后的后果 , MySQL 层会再作过滤 .

 

      当然上面是偷懒的做法 , 比较正规的做法应该是在 1) 判断大小的时候 , 0.5 取整为 1, 这样判断到 1=1, 就会标记为 HA_READ_KEY_OR_NEXT.

2
0
分享到:
评论
3 楼 丁林.tb 2012-08-29  
@wj0715208
因为0.4被四舍五入成0了
2 楼 wj0715208 2012-08-25  
你好,这个我在5.1上测试的时候确实有这个bug,根据你分析的原因,来理解的话,那么>=0.4和>=0.5的出来的结果应该是一样的,但是显示的结果却是不一样的?请问我理解有什么问题?
测试的结果:
mysql> select  * from int_index force index(a) where a>=0.4;
+---+------+
| a | b    |
+---+------+
| 1 |    2 |
| 2 |    5 |
| 3 |    8 |
| 4 |    6 |
+---+------+
4 rows in set (0.00 sec)

mysql> select  * from int_index force index(a) where a>=0.5;
+---+------+
| a | b    |
+---+------+
| 2 |    5 |
| 3 |    8 |
| 4 |    6 |
+---+------+
3 rows in set (0.00 sec)
1 楼 babaoqi 2012-07-27  

我用的5.5.23版这个问题应该是已经修复了

相关推荐

    前端:Uniapp 开发 后端:JAVA 数据库:MySQL 源码类型:WinForm 后台管理功能:

    前端:Uniapp 开发 后端:JAVA 数据库:MySQL 源码类型:WinForm 后台管理功能:

    MYSQL源码包:mysql-4.0.18.tar.gz

    由于MYSQL的源码包太大,一次上传不了,所以我做了分段压缩,这是第一段,请将两段一起下完解压使用。mysql源码包与Apache和PHP源码包一起安装可以搭建完整的Apache服务,另外两个我也有上传,谢谢关注!

    MySQL源码学习讲义.rar_MYSQL_mysql 源码

    MySQL源码学习讲义是一个关于深入理解MySQL数据库系统内核的资源集合,主要针对对数据库原理和MySQL实现感兴趣的开发者或数据库管理员。这份讲义可能是PDF文档形式,包含了MySQL的源码分析、设计原理以及实现机制的...

    mysql源码安装mysql源码安装

    mysql源码安装mysql源码安装mysql源码安装mysql源码安装mysql源码安装

    Mysql源码包安装步骤

    MySQL源码包安装步骤是一个复杂的过程,涉及到许多技术细节,对于想要深入了解数据库系统或进行定制化配置的IT专业人员尤其重要。以下将详细介绍这个过程。 首先,安装MySQL源码包前,确保你的操作系统环境满足...

    mysql源码安装脚本

    MySQL是一个开源的关系型数据库管理系统,广泛应用于Web应用程序,以其高效率、可扩展性和易用性而闻名。它支持SQL标准,并提供了多种存储引擎,如InnoDB(支持事务处理)和MyISAM(快速但不支持事务)。 2. **...

    mysql源码 和 redis 源码学习工程.zip

    MySQL是一个关系型数据库管理系统(RDBMS),而Redis则是一个内存数据结构存储系统,常被用作数据库、缓存和消息中间件。这里我们将深入探讨这两个源码的学习工程。 MySQL源码分析: 1. **SQL解析**:MySQL的解析器...

    MySql5.5源码安装包

    MySQL 5.5是MySQL数据库管理系统的一个重要版本,它在2010年发布,带来了许多性能提升和新特性。这个源码安装包是针对那些希望深入理解MySQL工作原理、进行自定义配置或者在没有预编译二进制包可用的情况下进行安装...

    Mysql源码安装手册.docx

    MySQL源码安装是一个复杂但必要的过程,特别是在特定的系统配置或需要自定义设置时。本文将详细介绍MySQL 5.5.11版本的源码安装步骤,并解释每个步骤的重要性和可能遇到的问题。 首先,MySQL 5.5版本开始使用CMake...

    mysql源码安装编译

    MySQL源码安装编译是一个复杂的过程,涉及到许多技术细节,对于想要深入了解MySQL内部工作原理或者定制特定功能的用户来说,这是必要的步骤。本教程将基于网络上的多种资源和实践经验,为您提供一个详尽的MySQL源码...

    mysql源码学习.zip

    MySQL是一款广泛使用的开源关系型数据库管理系统,其源码学习对于深入理解数据库的工作原理和技术细节具有重要意义。MySQL的源码分析可以让我们了解SQL语句如何被解析、查询优化、存储引擎的运作机制以及并发控制等...

    mysql源码编译工具

    Bison是一个解析器生成器,用于创建语法分析器,它在MySQL源码编译过程中起着至关重要的作用。这里推荐使用的是`bison-2.4.1-setup.exe`版本。安装这个工具后,你可以通过解析MySQL的Yacc(YACC:Yet Another ...

    bugfreee一个bug管理系统jsp+mysql

    总的来说,Bugfree是一个实用的bug管理系统,它充分利用了JSP的动态网页能力和MySQL的数据管理优势,为软件开发团队提供了一个便捷的工具,以更好地追踪、管理和解决项目中的bug,从而提升整个项目的质量和效率。...

    mysql源码包下载

    MySQL是一种广泛使用的开源关系型数据库...总的来说,对于那些需要高度定制和控制的环境,或者想要深入理解MySQL内部运作的开发者,源码安装是一个不错的选择。而对于日常使用,RPM或其它二进制包安装方式更为便捷。

    Mysql源码安装的详细文档

    你需要一个支持MySQL的Linux发行版,如Ubuntu、CentOS或Debian。确保系统已经更新并安装了必要的依赖包,例如GCC编译器、CMake构建系统、OpenSSL库、NCURSES库等。在Ubuntu上,你可以使用以下命令安装这些依赖: ``...

    MySQL源码安装和简单使用

    MySQL是一款广泛使用的...总结,MySQL源码安装和使用是一个涉及多方面知识的过程,包括操作系统、编译原理、数据库管理等。通过源码安装,你可以更深入地理解MySQL的工作原理,为日后的开发和运维工作打下坚实基础。

    mysql源码(mysql-8.2.0.tar.gz)

    MySQL是一种广泛使用的开源关系型数据库管理系统,其源代码的版本为mysql-8.2.0,这代表了MySQL的一个特定开发阶段。在这个版本中,开发者和研究者可以深入理解MySQL的内部工作原理,进行定制化开发或者排查问题。...

    MySQL源码mysql-5.7.22

    MySQL最新GA源码;mysql-5.7.23 zip包;使用zip 命令解压缩

    mysql源码(mysql-8.2.0.zip)

    `mysql-8.2.0.zip`是MySQL的一个特定版本,以下是关于这个版本的一些关键知识点: 1. **版本更新**:MySQL 8.2.0是一个重要的里程碑,它可能包含了自上一个稳定版本以来的大量改进和新特性。通常,新版本会带来性能...

Global site tag (gtag.js) - Google Analytics