1、myisam存儲引擎mysql
1. 數據庫版本:阿里雲RDS MySQL5.1sql
mysql> select @@version;
+-------------------------------+
| @@version |
+-------------------------------+
| 5.1.61-Alibaba-rds-201404-log |
+-------------------------------+
1 row in set (0.00 sec)數據庫
2. 測試的表結構信息服務器
mysql> show create table tb2\G
*************************** 1. row ***************************
Table: tb2
Create Table: CREATE TABLE `tb2` (
`a` varchar(255) DEFAULT NULL,
`b` varchar(255) DEFAULT NULL,
`c` varchar(255) DEFAULT NULL,
`d` varchar(1000) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)測試
3. 測試加索引阿里雲
(1)添加單列索引,可以添加成功(報出warning),但實際添加的是前綴索引。.net
mysql> alter table tb2 add index idx1 (d);
Query OK, 0 rows affected, 2 warnings (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0code
mysql> show warnings;
+---------+------+----------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 1000 bytes |
| Warning | 1071 | Specified key was too long; max key length is 1000 bytes |
+---------+------+----------------------------------------------------------+
2 rows in set (0.00 sec)orm
表結構信息:排序
mysql> show create table tb2\G
*************************** 1. row ***************************
Table: tb2
Create Table: CREATE TABLE `tb2` (
`a` varchar(255) DEFAULT NULL,
`b` varchar(255) DEFAULT NULL,
`c` varchar(255) DEFAULT NULL,
`d` varchar(1000) DEFAULT NULL,
KEY `idx1` (`d`(333))
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
(2)添加組合索引,會執行失敗。
mysql> alter table tb2 add index idx1 (a,b);
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
4. 分析
myisam存儲引擎在建立索引的時候,索引鍵長度是有一個較爲嚴格的長度限制的,全部索引鍵最大長度總和不能超過1000,並且不是實際數據長度的總和,而是索引鍵字段定義長度的總和。
主要字符集的計算方式:
latin1 = 1 byte = 1 character
uft8 = 3 byte = 1 character
gbk = 2 byte = 1 character
2、innodb存儲引擎
1. 表結構信息:
mysql> create table tb1 (a varchar(255), b varchar(255), c varchar(255), d varchar(1000));
Query OK, 0 rows affected (0.01 sec)
2. 添加組合索引,報出waring,實際在某個單列上添加的是前綴索引
mysql> alter table tb1 add index idx1(a,b,c,d);
Query OK, 0 rows affected, 2 warnings (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
+---------+------+---------------------------------------------------------+
2 rows in set (0.00 sec)
3. 添加單列索引,報出waring,實際添加的是前綴索引
mysql> alter table tb1 add index idx2(d);
Query OK, 0 rows affected, 2 warnings (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show warnings;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
| Warning | 1071 | Specified key was too long; max key length is 767 bytes |
+---------+------+---------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> show create table tb1\G
*************************** 1. row ***************************
Table: tb1
Create Table: CREATE TABLE `tb1` (
`a` varchar(255) DEFAULT NULL,
`b` varchar(255) DEFAULT NULL,
`c` varchar(255) DEFAULT NULL,
`d` varchar(1000) DEFAULT NULL,
KEY `idx1` (`a`,`b`,`c`,`d`(255)),
KEY `idx2` (`d`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
4. 分析:
默認狀況下,InnoDB 引擎單一字段索引的長度最大爲 767 字節,一樣的,前綴索引也有一樣的限制。當使用 UTF-8 字符集,每個字符使用 3 字節來存儲,在 TEXT 或者 VARCHAR 類型的字段上創建一個超過 255 字符數的前綴索引時就會遇到問題。能夠啓用服務器選項 innodb_large_prefix
使得這個限制增長到 3072 字節,並且表的 row_format 須要使用 compressed 或者 dynamic。
3、使用前綴索引帶來的風險:
INNODB的索引會限制單獨Key的最大長度爲767字節,超過這個長度必須創建小於等於767字節的前綴索引。
此外,BLOB和TEXT類型的列只能建立前綴索引。
前綴索引能提升索引創建速度和檢索速度,可是下面狀況是沒法使用前綴索引的:
仍是在上面的測試表上:
mysql> explain select * from tb1 order by d;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | tb1 | ALL | NULL | NULL | NULL | NULL | 5 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
mysql> explain select * from tb1 group by d; +----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ | 1 | SIMPLE | tb1 | ALL | NULL | NULL | NULL | NULL | 5 | Using temporary; Using filesort | +----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 1 row in set (0.00 sec)