MySQL索引列長度


前言

MySQL支持的單列索引長度是3072bytes,單列索引長度限制取決於:字段類型、字符集、創建表指定的ROW_FORMA格式。

 

索引長度計算:

  • 索引字段,如果NULL,則需要占用一個字節來記錄值是否為NULL。
  • 定長字段,如INT占4個字節、DATE占3個字節、CHAR(N)占N個字符。(注意字符與字節的區別,一個字符占用的字節取決於當前的字符集)
  • 變長字段,如VARCHAR(N)占用N個字符+2個字節(記錄長度)。

 

字符集長度

(root@localhost) [information_schema]> select * from information_schema.CHARACTER_SETS;
+--------------------+----------------------+---------------------------------+--------+
| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION                     | MAXLEN |
+--------------------+----------------------+---------------------------------+--------+
| big5               | big5_chinese_ci      | Big5 Traditional Chinese        |      2 |
| dec8               | dec8_swedish_ci      | DEC West European               |      1 |
| cp850              | cp850_general_ci     | DOS West European               |      1 |
| hp8                | hp8_english_ci       | HP West European                |      1 |
| koi8r              | koi8r_general_ci     | KOI8-R Relcom Russian           |      1 |
| latin1             | latin1_swedish_ci    | cp1252 West European            |      1 |
| latin2             | latin2_general_ci    | ISO 8859-2 Central European     |      1 |
| swe7               | swe7_swedish_ci      | 7bit Swedish                    |      1 |
| ascii              | ascii_general_ci     | US ASCII                        |      1 |
| ujis               | ujis_japanese_ci     | EUC-JP Japanese                 |      3 |
| sjis               | sjis_japanese_ci     | Shift-JIS Japanese              |      2 |
| hebrew             | hebrew_general_ci    | ISO 8859-8 Hebrew               |      1 |
| tis620             | tis620_thai_ci       | TIS620 Thai                     |      1 |
| euckr              | euckr_korean_ci      | EUC-KR Korean                   |      2 |
| koi8u              | koi8u_general_ci     | KOI8-U Ukrainian                |      1 |
| gb2312             | gb2312_chinese_ci    | GB2312 Simplified Chinese       |      2 |
| greek              | greek_general_ci     | ISO 8859-7 Greek                |      1 |
| cp1250             | cp1250_general_ci    | Windows Central European        |      1 |
| gbk                | gbk_chinese_ci       | GBK Simplified Chinese          |      2 |
| latin5             | latin5_turkish_ci    | ISO 8859-9 Turkish              |      1 |
| armscii8           | armscii8_general_ci  | ARMSCII-8 Armenian              |      1 |
| utf8               | utf8_general_ci      | UTF-8 Unicode                   |      3 |
| ucs2               | ucs2_general_ci      | UCS-2 Unicode                   |      2 |
| cp866              | cp866_general_ci     | DOS Russian                     |      1 |
| keybcs2            | keybcs2_general_ci   | DOS Kamenicky Czech-Slovak      |      1 |
| macce              | macce_general_ci     | Mac Central European            |      1 |
| macroman           | macroman_general_ci  | Mac West European               |      1 |
| cp852              | cp852_general_ci     | DOS Central European            |      1 |
| latin7             | latin7_general_ci    | ISO 8859-13 Baltic              |      1 |
| utf8mb4            | utf8mb4_general_ci   | UTF-8 Unicode                   |      4 |
| cp1251             | cp1251_general_ci    | Windows Cyrillic                |      1 |
| utf16              | utf16_general_ci     | UTF-16 Unicode                  |      4 |
| utf16le            | utf16le_general_ci   | UTF-16LE Unicode                |      4 |
| cp1256             | cp1256_general_ci    | Windows Arabic                  |      1 |
| cp1257             | cp1257_general_ci    | Windows Baltic                  |      1 |
| utf32              | utf32_general_ci     | UTF-32 Unicode                  |      4 |
| binary             | binary               | Binary pseudo charset           |      1 |
| geostd8            | geostd8_general_ci   | GEOSTD8 Georgian                |      1 |
| cp932              | cp932_japanese_ci    | SJIS for Windows Japanese       |      2 |
| eucjpms            | eucjpms_japanese_ci  | UJIS for Windows Japanese       |      3 |
| gb18030            | gb18030_chinese_ci   | China National Standard GB18030 |      4 |
+--------------------+----------------------+---------------------------------+--------+

創建索引

MySQL 8.X

MySQL 8.X默認支持的單列索引索引最大長度是3072bytes。

 

數據庫版本:MySQL 8.0.24

字符集:utf8mb4(一個字符占4bytes)

索引字段:變長varchar(n) 

 

創建表

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB DEFAULT CHARACTER SET UTF8MB4;

 

計算支持的最大單列索引長度是(3072-2)/4=767.5

指定索引長度為767

(root@localhost) [test]> CREATE INDEX `index_items_key` ON `items` (`key_info`(767));
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為768

(root@localhost) [test]> CREATE INDEX `index_items_key` ON `items` (`key_info`(768));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為大於768則失敗,報key超過了最大長度

(root@localhost) [test]> CREATE INDEX `index_items_key` ON `items` (`key_info`(769));
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

MySQL 5.7

MySQL 5.7默認支持的單列索引索引最大長度是3072bytes,可以通過修改innodb_large_prefix = OFF改變默認支持長度為767bytes。

引用官檔:https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_file_format

 

數據庫版本:MySQL 5.7.33

字符集:utf8mb4(一個字符占4bytes)

索引字段:變長字段varchar(n) 

 

創建表

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB DEFAULT CHARACTER SET UTF8MB4;

 

計算支持的最大單列索引長度是(3072-1-2)/4=767.5

指定索引長度為767

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(767));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為768

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(768));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度大於768則會失敗

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(769));
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

 

調整innodb_large_prefix = OFF,則會限制索引單列的最大長度為767bytes。

(root@localhost) [gaoyu]> set @@global.innodb_large_prefix = 0;
Query OK, 0 rows affected, 1 warning (0.00 sec)

 

計算支持的最大單列索引長度是(767-1-2)/4=191

 

指定索引長度為191

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(191));
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為192 VARCHAR(192)則會失敗

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(192));
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

MySQL 5.6

MySQL 5.6默認支持的單列索引索引最大長度是767bytes,可以通過修改innodb_large_prefix = ON、innodb_file_format = barracuda、innodb_file_per_table = true以及創建表時row_format=(DYNAMIC 或 COMPRESSED)更改默認支持長度為3072bytes。

引用官檔:https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_large_prefix

 

數據庫版本:MySQL 5.6.21

字符集:utf8mb4(一個字符占4bytes)

索引字段:變長字段varchar(n) 

 

創建表

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB DEFAULT CHARACTER SET UTF8MB4;

 

計算支持的最大單列索引長度是(767-1-2)/4=191

 

指定索引長度為191

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(191));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為192則失敗

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(192));
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

 

變更參數,此時支持的索引最大長度是3072bytes

set @@global.innodb_large_prefix = ON;
set @@global.innodb_file_format = barracuda;
set @@global.innodb_file_per_table = true;

 

重新創建表並指定row_format=DYNAMIC 或 COMPRESSED

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB DEFAULT CHARACTER SET UTF8MB4 ROW_FORMAT=DYNAMIC;

 

計算支持的最大單列索引長度是(3072-1-2)/4=767.5

指定索引長度為767 

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(767));
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

指定索引長度為768

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(768));
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

索引長度大於768則會失敗

(root@localhost) [gaoyu]> CREATE INDEX `index_items_key` ON `items` (`key_info`(769));
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM