Mysql

為什麼 InnoDB 表預設使用 UNIQUE 約束而不是 PRIMARY KEY?

  • March 27, 2014

在我的 MySQL 數據庫中,我有一個包含 4 列的表,其中PRIMRAY KEY2 列具有 aFOREIGN KEY CONSTRAINT和一個UNIQUE 索引,除PRIMARY KEY.

SHOW CREATE TABLE: _

CREATE TABLE `zdb_userbeschikbaarheid` (
 `UserBeschikbaarheid_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `UB_User_ID` int(10) unsigned NOT NULL,
 `UB_PlanDagdeelTaak_ID` int(10) unsigned NOT NULL,
 `UB_Datum` date NOT NULL,
 PRIMARY KEY (`UserBeschikbaarheid_ID`),
 UNIQUE KEY `UQ_UB_User_ID_PlanDagdeelTaak_ID_Datum` (`UB_Datum`,`UB_User_ID`,`UB_PlanDagdeelTaak_ID`),
 KEY `FK_UB_User_ID` (`UB_User_ID`),
 KEY `FK_UB_PlanDagdeelTaak_ID` (`UB_PlanDagdeelTaak_ID`),
 CONSTRAINT `FK_UB_PlanDagdeelTaak_ID` FOREIGN KEY (`UB_PlanDagdeelTaak_ID`) REFERENCES `zdb_plandagdeeltaak` (`PlanDagdeelTaak_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
 CONSTRAINT `FK_UB_User_ID` FOREIGN KEY (`UB_User_ID`) REFERENCES `zdb_user` (`User_ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=522 DEFAULT CHARSET=utf8

由於某些奇怪的原因,當我選擇完整表時,它使用的是UNIQUE索引而不是PRIMARY KEY. 一個EXPLAIN SELECT * FROM zdb_userbeschikbaarheid;產量:

id  select_type table                   type    possible_keys   
1   SIMPLE      zdb_userbeschikbaarheid index   \N

key                                     key_len ref rows    Extra
UQ_UB_User_ID_PlanDagdeelTaak_ID_Datum  11      \N  415     Using index

PRIMARY KEY在我明確告訴它ORDER BY主鍵之前它不會使用。

EXPLAIN SELECT * FROM zdb_userbeschikbaarheid ORDER BY UserBeschikbaarheid_ID;

id  select_type table                   type    possible_keys
1   SIMPLE      zdb_userbeschikbaarheid index   \N

key     key_len ref rows    Extra
PRIMARY 4       \N  415     \N

UNIQUE KEY選擇 而不是似乎很奇怪PRIMARY KEY

是什麼導致了這種行為,它是我的數據庫的潛在問題嗎?如果可能的話,我怎樣才能將其更改為PRIMARY KEY預設使用?

對於 InnoDB 表,所有二級索引都包括聚集索引的列(即主鍵),並附加在末尾。所以你的唯一索引實際上有 4 列,你定義的 3 列加上 1 個主鍵列。

當執行需要全表掃描的查詢時,兩個索引都有所需的所有數據,因此優化器可以自由選擇兩個索引中的任何一個。事實上,正如InnoDB 表和索引結構中所解釋的,聚集索引包含一些額外的資訊,每行花費 13 個字節:

聚集索引中的記錄包含所有使用者定義列的欄位。此外,還有一個 6 字節的事務 ID 欄位和一個 7 字節的滾動指針欄位。

這使您的唯一索引比主鍵索引更窄,這就是優化器選擇它的原因。

引用自:https://dba.stackexchange.com/questions/61935