zoukankan      html  css  js  c++  java
  • MySQL隐式转换测试

     
    Preface
     
        There're various data type in MySQL such as number,string,date,time,lob,etc.The data type will convert implicitly if we don't use a proper operand in a SQL statement which may even contain expressions.These implicit conversion of data type sometimes may lead to performance issues because it will make the indexes on the very columns be useless.We should do our best to avoid implicit conversion in our product environment by explicitly specifying the same data type with the relevant column.
        The principle of implicit conversion in MySQL is to make the operation be as compatible as possible and not return result(In most cases,it may be wrong).Athough we can use cast() and convert() function to convert the data type,but it's better to speicify correct data type directly on account of consideration of performance.Notice that you'de better always keep functions in the right side.
     
    Example
     
    Test the implicit conversion in function convert() and cast().
     1 (zlm@192.168.1.101 3306)[zlm]>select cast('2abc' as unsigned) from dual;
     2 +--------------------------+
     3 | cast('2abc' as unsigned) |
     4 +--------------------------+
     5 |                        2 |
     6 +--------------------------+
     7 1 row in set, 1 warning (0.00 sec)
     8 
     9 (zlm@192.168.1.101 3306)[zlm]>select convert('2abc',unsigned) from dual;
    10 +--------------------------+
    11 | convert('2abc',unsigned) |
    12 +--------------------------+
    13 |                        2 |
    14 +--------------------------+
    15 1 row in set, 1 warning (0.00 sec)
    16 
    17 //Function cast() and convert() turned the string '2abc' to number.
    18 //The result became 2 what means the string begin with number only keep the first number remain.
    19 
    20 (zlm@192.168.1.101 3306)[zlm]>select convert('abc',unsigned) from dual;
    21 +-------------------------+
    22 | convert('abc',unsigned) |
    23 +-------------------------+
    24 |                       0 |
    25 +-------------------------+
    26 1 row in set, 1 warning (0.00 sec)
    27 
    28 (zlm@192.168.1.101 3306)[zlm]>select cast('abc' as unsigned) from dual;
    29 +-------------------------+
    30 | cast('abc' as unsigned) |
    31 +-------------------------+
    32 |                       0 |
    33 +-------------------------+
    34 1 row in set, 1 warning (0.00 sec)
    35 
    36 //If there's no number prefix,the result turns out to be zero(integer type here).
    37 
    38 (zlm@192.168.1.101 3306)[zlm]>select '3'=convert('3abc',unsigned);
    39 +-----------------------------+
    40 | '0'=convert('abc',unsigned) |
    41 +-----------------------------+
    42 |                           1 |
    43 +-----------------------------+
    44 1 row in set, 1 warning (0.00 sec)
    45 
    46 (zlm@192.168.1.101 3306)[zlm]>select '3'=cast('3abc' as unsigned);
    47 +-----------------------------+
    48 | '0'=cast('abc' as unsigned) |
    49 +-----------------------------+
    50 |                           1 |
    51 +-----------------------------+
    52 1 row in set, 1 warning (0.00 sec)
    53 
    54 (zlm@192.168.1.101 3306)[zlm]>select 3=convert('3abc',unsigned);
    55 +-----------------------------+
    56 | '0'=convert('abc',unsigned) |
    57 +-----------------------------+
    58 |                           1 |
    59 +-----------------------------+
    60 1 row in set, 1 warning (0.00 sec)
    61 
    62 (zlm@192.168.1.101 3306)[zlm]>select 3=cast('3abc' as unsigned);
    63 +-----------------------------+
    64 | '0'=cast('abc' as unsigned) |
    65 +-----------------------------+
    66 |                           1 |
    67 +-----------------------------+
    68 1 row in set, 1 warning (0.00 sec)
    69 
    70 //All the rusults are 1 what means the implicit conversion occurs. 

    Test the implicit conversion in expression and function concat().

     1 (zlm@192.168.1.101 3306)[zlm]>select 10+'abc' from dual;
     2 +----------+
     3 | 10+'abc' |
     4 +----------+
     5 |       10 |
     6 +----------+
     7 1 row in set, 1 warning (0.01 sec)
     8 
     9  //The string 'abc' converted implicitly from string to number and got result of 10(10 + 0 = 0).
    10 
    11 (zlm@192.168.1.101 3306)[zlm]>select concat(10,'abc') from dual;
    12 +------------------+
    13 | concat(10,'abc') |
    14 +------------------+
    15 | 10abc            |
    16 +------------------+
    17 1 row in set (0.00 sec)
    18 
    19 //The number 10 was converted implicitly to string and concantenated by string 'abc'.
    20 
    21 (zlm@192.168.1.101 3306)[zlm]>select 10+'abc'=concat(10,'abc');
    22 +---------------------------+
    23 | 10+'abc'=concat(10,'abc') |
    24 +---------------------------+
    25 |                         1 |
    26 +---------------------------+
    27 1 row in set, 1 warning (0.00 sec)
    28 
    29 //What may astonish us is that the result became 1,that is,implicit conversion occured again.
    30 
    31 (zlm@192.168.1.101 3306)[zlm]>select 10=concat(10,'abc')-'abc';
    32 +---------------------------+
    33 | 10=concat(10,'abc')-'abc' |
    34 +---------------------------+
    35 |                         1 |
    36 +---------------------------+
    37 1 row in set, 1 warning (0.00 sec)
    38 
    39 //Moving the string 'abc' to the right side didn't influence the result of 1.

    Test the implicit conversion in table.

      1 (zlm@192.168.1.101 3306)[sysbench]>desc sbtest1;
      2 +-------+-----------+------+-----+---------+----------------+
      3 | Field | Type      | Null | Key | Default | Extra          |
      4 +-------+-----------+------+-----+---------+----------------+
      5 | id    | int(11)   | NO   | PRI | NULL    | auto_increment |
      6 | k     | int(11)   | NO   | MUL | 0       |                |
      7 | c     | char(120) | NO   |     |         |                |
      8 | pad   | char(60)  | NO   |     |         |                |
      9 +-------+-----------+------+-----+---------+----------------+
     10 4 rows in set (0.00 sec)
     11 
     12 (zlm@192.168.1.101 3306)[sysbench]>select * from sbtest1 limit 5;
     13 +----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
     14 | id | k    | c                                                                                                                       | pad                                                         |
     15 +----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
     16 |  1 | 4993 | 83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330 | 67847967377-48000963322-62604785301-91415491898-96926520291 |
     17 |  2 | 5020 | 38014276128-25250245652-62722561801-27818678124-24890218270-18312424692-92565570600-36243745486-21199862476-38576014630 | 23183251411-36241541236-31706421314-92007079971-60663066966 |
     18 |  3 | 5044 | 33973744704-80540844748-72700647445-87330233173-87249600839-07301471459-22846777364-58808996678-64607045326-48799346817 | 38615512647-91458489257-90681424432-95014675832-60408598704 |
     19 |  4 | 5021 | 37002370280-58842166667-00026392672-77506866252-09658311935-56926959306-83464667271-94685475868-28264244556-14550208498 | 63947013338-98809887124-59806726763-79831528812-45582457048 |
     20 |  5 | 4999 | 44257470806-17967007152-32809666989-26174672567-29883439075-95767161284-94957565003-35708767253-53935174705-16168070783 | 34551750492-67990399350-81179284955-79299808058-21257255869 |
     21 +----+------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
     22 5 rows in set (0.00 sec)
     23 
     24 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where id='1';
     25 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     26 | id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
     27 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     28 |  1 | SIMPLE      | sbtest1 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
     29 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     30 1 row in set, 1 warning (0.00 sec)
     31 
     32 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where id=cast(1 as char);
     33 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     34 | id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
     35 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     36 |  1 | SIMPLE      | sbtest1 | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
     37 +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
     38 1 row in set, 1 warning (0.00 sec)
     39 
     40 //Despite I've specified 1 as string above,the queries still return result with primary key.
     41 
     42 (zlm@192.168.1.101 3306)[sysbench]>alter table sbtest1 add unique(c); //Add a unique key on column c(char type).
     43 Query OK, 0 rows affected (4 min 58.75 sec) //It cost almost 5 mins.
     44 Records: 0  Duplicates: 0  Warnings: 0
     45 
     46 (zlm@192.168.1.101 3306)[sysbench]>desc sbtest1;
     47 +-------+-----------+------+-----+---------+----------------+
     48 | Field | Type      | Null | Key | Default | Extra          |
     49 +-------+-----------+------+-----+---------+----------------+
     50 | id    | int(11)   | NO   | PRI | NULL    | auto_increment |
     51 | k     | int(11)   | NO   | MUL | 0       |                |
     52 | c     | char(120) | NO   | UNI |         |                |
     53 | pad   | char(60)  | NO   |     |         |                |
     54 +-------+-----------+------+-----+---------+----------------+
     55 4 rows in set (0.00 sec)
     56 
     57 (zlm@192.168.1.101 3306)[sysbench]>select count(*) from sbtest1;
     58 +----------+
     59 | count(*) |
     60 +----------+
     61 |  3698838 |
     62 +----------+
     63 1 row in set (3.52 sec)
     64 
     65 //Query 1
     66 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where c=83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330;
     67 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     68 | id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
     69 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     70 |  1 | SIMPLE      | sbtest1 | NULL       | ALL  | c             | NULL | NULL    | NULL | 3423050 |    10.00 | Using where |
     71 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     72 1 row in set, 3 warnings (0.00 sec)
     73 
     74 //Query 2
     75 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where c='83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330';
     76 +----+-------------+---------+------------+-------+---------------+------+---------+-------+------+----------+-------+
     77 | id | select_type | table   | partitions | type  | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
     78 +----+-------------+---------+------------+-------+---------------+------+---------+-------+------+----------+-------+
     79 |  1 | SIMPLE      | sbtest1 | NULL       | const | c             | c    | 360     | const |    1 |   100.00 | NULL  |
     80 +----+-------------+---------+------------+-------+---------------+------+---------+-------+------+----------+-------+
     81 1 row in set, 1 warning (0.01 sec)
     82 
     83 //Query 3
     84 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where c like 83868641912;
     85 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     86 | id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
     87 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     88 |  1 | SIMPLE      | sbtest1 | NULL       | ALL  | c             | NULL | NULL    | NULL | 3423050 |    11.11 | Using where |
     89 +----+-------------+---------+------------+------+---------------+------+---------+------+---------+----------+-------------+
     90 1 row in set, 2 warnings (0.00 sec)
     91 
     92 //Query 4
     93 (zlm@192.168.1.101 3306)[sysbench]>explain select * from sbtest1 where c like '83868641912%';
     94 +----+-------------+---------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
     95 | id | select_type | table   | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                 |
     96 +----+-------------+---------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
     97 |  1 | SIMPLE      | sbtest1 | NULL       | range | c             | c    | 360     | NULL |    1 |   100.00 | Using index condition |
     98 +----+-------------+---------+------------+-------+---------------+------+---------+------+------+----------+-----------------------+
     99 1 row in set, 1 warning (0.00 sec)
    100 
    101 //The implicit conversion occured in query 1 and query 3.They cannot use the index on column c.
    102 //In query 4,it even used ICP feature of MySQL(Which is supported since version 5.6).
    Summary
    • The implicit conversion usually occurs to make the query to be as compatible as possible in MySQL.
    • The implicit conversion occurs in expression,function and condiction of queries.
    • The implicit conversion may lead to bad performance because it will prevent MySQL from using indexes on specific query columns.
    • We'd better specify the correct data type explicit when typing them in our query SQL statement to avoid the implicit conversion.
  • 相关阅读:
    你真的会玩SQL吗?让人晕头转向的三值逻辑
    SQL Server 索引维护:系统常见的索引问题
    MySQL Proxy 实现 MySQL 读写分离提高并发负载
    php 处理上百万条的数据库如何提高处理查询速度
    sql事务(Transaction)用法介绍及回滚实例
    数据库update的异常一例
    使用Java正则表达式提取字符串中的数字一例
    JodaTime library not available
    java web中日期Date类型在页面中格式化显示的三种方式
    深入剖析js命名空间函数namespace
  • 原文地址:https://www.cnblogs.com/aaron8219/p/9315497.html
Copyright © 2011-2022 走看看