1. 程式人生 > >關於mysql5.6 decimal 型別的幾個小bug

關於mysql5.6 decimal 型別的幾個小bug

bug 詳情見官介紹:

http://bugs.MySQL.com/bug.PHP?id=72056  (1)當儲存的decimal值超級大的時候,在沒有索引的情況下,mysql會認為所有的值一樣大

http://bugs.mysql.com/bug.php?id=72274  (2)當使用decimal 做分割槽key的時候,分割槽key無法正確過濾分割槽的問題


一,關於bug (1)

建立測試表:

 CREATE TABLE `decimalTest`(`value` DECIMAL(24,0) NOT NULL);

插入測試資料:

 INSERT INTO `decimalTest`(`value`) VALUES('100000000000000000000001'), ('100000000000000000000002'), ('100000000000000000000003');

 INSERT INTO `decimalTest`(`value`) VALUES('1234'),('5678');

執行查詢:

(a),字串數字巨大值做條件:

SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';

+--------------------------+
|     value                      |
+--------------------------+
| 100000000000000000000001 |
| 100000000000000000000002 |
| 100000000000000000000003 |
+--------------------------+

查詢結果不對

(b),數值數字巨大值做條件:

 SELECT * FROM `decimalTest` WHERE `value` = 100000000000000000000002;
+--------------------------+
|       value                    |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+

查詢結果正確


==================這一部分是自己新增的,為了對比測試======================

(c)字串數值小值做條件

select * from  `decimalTest` WHERE `value` ='1234';

+-------+
| value |
+-------+
|  1234 |
+-------+

查詢結果正確

=======================================================================

(d)對欄位新增索引,然後重新執行(a)查詢

alter table decimalTest add index ind_decimal  (`value`);  

SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';
+--------------------------+
|       value                    |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+

結果正確

總結:當使用超大字串數值作為條件查詢時,mysql會將他們認為一樣大,這個時候需要加索引才可以避免錯誤,該bug在5.5、5.6都存在目前沒有修復


二,關於bug (2)

正常情況下decimal是不能直接作為分割槽key的,不過我們可以使用函式進行轉換來實現

建立測試表:

CREATE TABLE test(test DECIMAL(31,20) PRIMARY KEY)

 PARTITION BY RANGE(FLOOR(test))

(

PARTITION p0 VALUES LESS THAN(1),

PARTITION p1 VALUES LESS THAN(2)

) ;

插入測試資料:

insert into test values(0),(1);

檢視執行計劃


可以看到執行範圍查詢的時候沒有正確過濾分割槽,該bug也尚未修復。

在生成環境有用到5.6的並且使用decimal型別場景和上述兩種相同的希望大家注意一下。


參考:

http://bugs.mysql.com/bug.php?id=72056  

http://bugs.mysql.com/bug.php?id=72274 

bug 詳情見官介紹:

http://bugs.MySQL.com/bug.PHP?id=72056  (1)當儲存的decimal值超級大的時候,在沒有索引的情況下,mysql會認為所有的值一樣大

http://bugs.mysql.com/bug.php?id=72274  (2)當使用decimal 做分割槽key的時候,分割槽key無法正確過濾分割槽的問題


一,關於bug (1)

建立測試表:

 CREATE TABLE `decimalTest`(`value` DECIMAL(24,0) NOT NULL);

插入測試資料:

 INSERT INTO `decimalTest`(`value`) VALUES('100000000000000000000001'), ('100000000000000000000002'), ('100000000000000000000003');

 INSERT INTO `decimalTest`(`value`) VALUES('1234'),('5678');

執行查詢:

(a),字串數字巨大值做條件:

SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';

+--------------------------+
|     value                      |
+--------------------------+
| 100000000000000000000001 |
| 100000000000000000000002 |
| 100000000000000000000003 |
+--------------------------+

查詢結果不對

(b),數值數字巨大值做條件:

 SELECT * FROM `decimalTest` WHERE `value` = 100000000000000000000002;
+--------------------------+
|       value                    |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+

查詢結果正確


==================這一部分是自己新增的,為了對比測試======================

(c)字串數值小值做條件

select * from  `decimalTest` WHERE `value` ='1234';

+-------+
| value |
+-------+
|  1234 |
+-------+

查詢結果正確

=======================================================================

(d)對欄位新增索引,然後重新執行(a)查詢

alter table decimalTest add index ind_decimal  (`value`);  

SELECT * FROM `decimalTest` WHERE `value` = '100000000000000000000002';
+--------------------------+
|       value                    |
+--------------------------+
| 100000000000000000000002 |
+--------------------------+

結果正確

總結:當使用超大字串數值作為條件查詢時,mysql會將他們認為一樣大,這個時候需要加索引才可以避免錯誤,該bug在5.5、5.6都存在目前沒有修復


二,關於bug (2)

正常情況下decimal是不能直接作為分割槽key的,不過我們可以使用函式進行轉換來實現

建立測試表:

CREATE TABLE test(test DECIMAL(31,20) PRIMARY KEY)

 PARTITION BY RANGE(FLOOR(test))

(

PARTITION p0 VALUES LESS THAN(1),

PARTITION p1 VALUES LESS THAN(2)

) ;

插入測試資料:

insert into test values(0),(1);

檢視執行計劃


可以看到執行範圍查詢的時候沒有正確過濾分割槽,該bug也尚未修復。

在生成環境有用到5.6的並且使用decimal型別場景和上述兩種相同的希望大家注意一下。


參考:

http://bugs.mysql.com/bug.php?id=72056  

http://bugs.mysql.com/bug.php?id=72274