MySQL 类型转换引发的慢查询

阅读数:2206 发布时间:2016-10-04 11:14:55

作者:w4gyc 标签: w4gyc Mysql 类型转换 慢查询

MySQL 类型转换引发的慢查询

首先上一段Mysql官方文档:

The following rules describe how conversion occurs for comparison operations:

  • If both arguments in a comparison operation are strings, they are compared as strings.

  • If both arguments are integers, they are compared as integers.

  • Hexadecimal values are treated as binary strings if not compared to a number.

  • If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.

  • If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.

  • In all other cases, the arguments are compared as floating-point (real) numbers.

这段文档对数据比较环境下的数据类型转换规则做了详细介绍,翻译过来就是:

根据以上的说明,当where条件之后的值的类型和表结构不一致(int与varchar类型作比较)的时候,MySQL会做隐式的类型转换,都将其转换为浮点数在比较。

下面以两个例子具体说明,例子一:

img1

从上面可以很明显的看到由于appkey是varchar,而在where条件中不加'',需要将索引中的字符串转换成浮点数,但是由于'1',' 1','1a'都会比转化成1,故MySQL无法使用索引只能进行全表扫描,加了就可以用到索引,这扫描的行数可是天差地别,对于服务器的压力和响应时间自然也是天差地别的。

例子二:

img2

虽然poll_id的类型为bigint,但是SQL中添加了'',但是这个语句仍然用到了索引,因为索引建立在int的基础上,而将纯数字的字符串可以百分百转换成数字,故可以使用到索引,虽然也会进行一定的转换,消耗一定的资源,但是最终仍然使用了索引,不会产生慢查询,虽然扫描行数也不少,但是能用到索引就是好SQL。

同时还有一点需要注意:int,varchar进行比较都会转换成浮点数进行比较,而浮点数只有53bit,故当超过最大值的时候,比较会出现问题。

参考文献http://dev.mysql.com/doc/refman/5.5/en/type-conversion.html

相关文章推荐: