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.

猜你喜欢

转载自www.cnblogs.com/aaron8219/p/9315497.html