組合索引長度之和大於 767 bytes並無影響,當有某個字段定義長度大於 767 bytes(1000*3)時,僅產生告警,但不影響創建,超長字段會取前 255 字符作為前綴索引,並且組合索引中字段出現的順序並無關系。
為什么3072
InnoDB一個page的默認大小是 16 k。由於是Btree組織,要求葉子節點上一個page至少包含兩條記錄(否則就退化鏈表了)。所以一個記錄最多不能超過 8 k。又由於InnoDB的聚簇索引結構,一個二級索引要包含主鍵索引,因此每個單個索引不能超過 4 k(極端情況,pk和某個二級索引都達到這個限制)。由於需要預留和輔助空間,扣掉后不能超過 3500 ,取個“整數”就是(1024*3)。
單列索引限制
默認情況下,InnoDB 引擎單一字段索引的長度最大為 767 字節,同樣的,前綴索引也有同樣的限制。當使用 UTF-8 字符集,每一個字符使用 3 字節來存儲,767=256*3-1,在 TEXT 或者 VARCHAR 類型的字段上建立一個超過 255 字符數的前綴索引時就會遇到問題。至於為什么字符長度限制在 256 內,我猜是為提高索引效率,應為varchar類型需要額外的字節保留其長度信息,256 就將其限定在一個字節了。但是在5.5以后,開始支持4個字節的uutf8。255×4>767, 於是增加了一個參數叫做innodblargeprefix。這個參數默認值是OFF,當改為ON時,允許列索引最大達到 3072 字節。要求表的 row_format 需要使用 compressed 或者 dynamic
使用前綴索引帶來的風險:
INNODB的索引會限制單獨Key的最大長度為 767 字節,超過這個長度必須建立小於等於 767 字節的前綴索引。 此外,BLOB和TEXT類型的列只能創建前綴索引。 前綴索引能提高索引建立速度和檢索速度,但是下面情況是無法使用前綴索引的:
索引覆蓋掃描
通過索引的排序(order by, group by)
修改索引限制長度需要在my.ini配置文件中添加以下內容,並重啟:
#修改單列索引字節長度為767的限制,單列索引的長度變為3072
innodb_large_prefix=1
# Antelope(羚羊)是Built-in-InnoDB(MySQL內置的InnoDB)支持文件格式的代號,有兩種“數據表格式”(row_format):Redundant(冗余)、Compact(緊湊)
#Barracuda(梭子魚)是InnoDB Plugin支持的文件格式,在原來的基礎上新增了兩種數據表格式的支持:Dynamic 和 Compressed
#innodb_file_format在配置文件中指定;row_format則在創建數據表時指定
#同時Barracude也支持 old redundant and compact row formats
innodb_file_format=BARRACUDA
#InnoDB Plugin引入的新的文件格式,也引入較為完整的文件兼容性檢查,以防止誤操作非兼容的文件格式。兼容性檢查一共有三類:啟動數據庫時、創建數據表時、訪問數據表時。
#當數據庫啟動時候,參數innodb_file_format_check(>=5.1.38)會要求InnoDB在啟動時檢查當前數據表的格式。設置為ON時,如果檢測到不支持的格式,那么InnoDB會啟動失敗;設置為OFF時,檢測到不支持的僅會給出警告,並不會導致啟動失敗。
#當創建數據表時,InnoDB會依據參數InnoDB_file_format進行檢查,如果創建的數據表格式高於InnoDB_file_format,則創建會失敗。
#當訪問某個數據表(table-access)時,InnoDB也會進行兼容性檢查。只要當前運行的InnoDB版本能夠支持的格式,都能夠被訪問,無論參數InnoDB_file_format的配置。
#把innodb_file_format_check設置為OFF是很危險的。在InnoDB啟動后,一般需要做一些恢復工作,例如Double write buffer/Insert buffer中的數據處理(這依賴於innodb_fast_shutdown參數),試想如果成功啟動,但是某些表是不支持的格式,但是InnoDB仍然安裝舊版本做恢復,這可能會毀掉相關數據。
#所以,一般建議innodb_file_format_check設置為ON。如果是OFF,關閉InnoDB的innodb_fast_shutdown參數務必設置成0
innodb_file_format_check=1
在創建表的時候需要指定表的行格式為dynamic ROW_FORMAT=DYNAMIC;
---------------------