天天看点

Precision和Length对MySQL执行结果的影响

Precision和Length对MySQL执行结果的影响是什么?

要回答这个问题,首先概念上要把Precision和Length区分开。Precision表示数值的精度,Length表示数值展示的宽度。他们的关系如下:

Length = Function(Precision, Scale, DateType)
           

数值列有zerofill修饰的情况下,它转化成字符串时,转化结果的Length受Precision影响。举例如下:

mysql> create table t (i int primary key, j int zerofill, k int(2) zerofill);
Query OK, 0 rows affected (0.05 sec)

mysql> insert into t values (1,1,1);
Query OK, 1 row affected (0.02 sec)


mysql> select * from t;
+---+------------+------+
| i | j          | k    |
+---+------------+------+
| 1 | 0000000001 |   01 |
+---+------------+------+
1 row in set (0.01 sec)


mysql> select substr(j, 1,1)  from t;
+----------------+
| substr(j, 1,1) |
+----------------+
| 0              |
+----------------+
1 row in set (0.00 sec)

mysql> select substr(j, 1, 20)  from t;
+------------------+
| substr(j, 1, 20) |
+------------------+
| 0000000001       |
+------------------+
1 row in set (0.00 sec)
           

OK,很明显,Precision对于MySQL执行结果是有影响的。那么,换个问题,Length对执行结果有影响吗?我认为:没有。不过,如何证明没有呢?穷举法,穷尽MySQL源码即可(^__^)

然后要理解Length是什么

为什么要引入Length呢?看下面一段解释

unsigned long length

The width of the field. This corresponds to the display length, in bytes.

The server determines the length value before it generates the result set, so this is the minimum length required for a data type capable of holding the largest possible value from the result column, without knowing in advance the actual values that will be produced by the query for the result set.

可见,Length是用来帮助客户端在不知道真实数据的情况下准备好缓冲区,将来存放获取到的真实数据。什么场景下需要这么搞呢?执行prepare语句的时候。MySQL bug系统中就有这么一个bug ,由于Length计算错误,导致客户端内存飙升的问题:Prepare模式下,MySQL告诉客户端,c1这一列的length是1.4GB,客户端遵照“指示”分配了1.4G这么大的缓冲区,用于存放将要获取到的数据,于是,悲剧发生。

理解了上面这些内容之后,就能理解MySQL为啥在Length推导这件事上面只是做到“尽力而为”:Length最终用于指导客户端的内存分配,只要确保Length不小于理论值,就不会出大问题。那帮committer估计心里想的是:“哼哼,我能做到尽力而为,已经很够意思了。很多人直接给你一个最大值,你不也屁颠儿地用得不亦乐乎么?”

回到正题上来。Precision和Length对MySQL执行结果的影响是什么?本文给出的答案如下:

  • Length是否对执行结果有影响?没有。
  • Precision是否对执行结果有影响?有。影响过程和zerofill有关,见上例。

附加结论:

  • Precision是否需要推导?不需要。
  • Length推导还要不要?要。
  • Length推导还要不要精确,并和MySQL兼容?不要。
  • Length推导对谁最重要?字符串。
  • Length推导对谁比较重要?Decimal。
  • Length推导对谁最最不重要?Int、Float、Double。