天天看點

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。