大部分情況下,MySQL Innodb中主鍵的效能是不是被浪費了?

時間 2021-12-26 21:29:02

1樓:Learner

上面很多人回答,提到了自增主鍵可以提高插入效率,能提高多少呢?

看下innodb page 結構,不難發現,其實,無論你用什麼主鍵,record都是順序寫入page 的,page 尾部有個索引,這個才會產生資料遷移,並且這個索引是優化設計的,儘量減少了資料遷移,這個索引真的很小,影響沒有想象那麼大

所以我認為,不要為了這點效能而強行自增主鍵,還是設計適合自己業務的主鍵最好(主鍵選取插入相關只是考慮的一部分,其他不展開了)

!!!record 在磁碟儲存的順序,真的不是主鍵的順序

2樓:哎呀

不會的,主鍵索引對應的結構和其他索引的資料結構不同,雖然都是Btree,主鍵索引的子節點指向的是具體的列位址,一般索引的子節點指向的是其主鍵標示,所有無論你搜尋還是加鎖,都會走主鍵,

3樓:CocaLi

1、Innodb引擎是索引組織表,所謂索引組織表就是資料的插入順序是根據主鍵的順序來的,如果設定業務ID為主鍵,沒有辦法保證業務ID自增的話,那麼新資料的插入會引起行遷移,這就是為什麼很多回答中提到自增主鍵會提公升插入效率。

2、Innodb引起表中所有的二級索引(非主鍵)的key值記錄的都是主鍵,所以盡量要求主鍵的字段型別簡單,而業務開發一般會用char/varchar來設計業務ID,用varchar和int來設計主鍵,影響的不僅僅是主鍵的長度,該錶上所有的索引都會變大。從SQL優化的角度來說,優化的本質是減少IO,而減少IO最直接的方法其實就是設計最簡單的字段型別(包括索引)。

3、從運維DBA的角度來說,你們遇到過非自增主鍵,十幾億條記錄的表,要分批操作時候的絕望嗎?如果有自增主鍵,直接指定primary key操作,會大大簡化後期維護操作。當然你說可以通過updatetime欄位來操作,但是不一定所有的表都有自更新的時間戳字段啊,而且也不一定能保證時間戳有索引啊。

4、當然你也可以說如果我的表只有幾百條資料,也不會有什麼分批操作的需求,這就跟這樣的表要不要設計索引一樣。當然考慮實際情況或者業務場景,這樣的表不設主鍵或索引也是可以接受的,但是從開發規範來說,難道我制定主鍵規範的時候只說大家根據實際需求來嗎?

所以一般的開發規範中都會要求設計自增ID為主鍵。

4樓:

這個問題在很多使用者上確實很有共性,先說結論,是很浪費,而且很多使用者都存在這樣的浪費,好的設計既不會用無意義主鍵也不會讓二級索引分布的過散。

可以參考ddia來想想如何做有意義的sequence id 設計可以參考mysql clustered index 來看如何讓二級索引的查詢變高效

先說到這裡,有關注度可以深入的來說說。

5樓:

Innodb是乙個多版本的儲存引擎,當插入新的一行時,乙個包含著row ID的6位元組自增的DB_ROW_ID會被自動生成,如果Innodb同時會自動生成乙個聚集索引,那麼這個索引會包含這個row ID的值,否則DB_ROW_ID列不會出現在任何索引中。

那麼什麼時候Innodb會自動生成聚集索引呢,通常,聚集索引和主鍵是同義的,當你指定乙個主鍵時,Innodb使用它作為聚集索引,我們知道MySQL中資料以B+樹的形式組織,預設情況下,聚集索引的葉子節點會儲存所有的資料,而二級索引只儲存索引列和主鍵列,最終它是依據主鍵列來找到所有的資料的,從這一點來看,的確使用二級索引會多一次io開銷,當然,有些時候我們通過二級索引就能找到需要的列而並不是所有的列。

但如果你沒有指定主鍵,Innodb預設選擇第乙個非空的唯一索引作為聚集索引,也就是說所有資料會以這乙個唯一索引列組織,這種情況下,根據這個唯一索引列的查詢顯然只需要一次就獲得所有資料。

如果上面的情況都不符合,Innodb會在乙個包含row ID的合成列上(應該就是DB_ROW_ID)上隱式的生成,每行資料是根據這個ID排序的,當插入新的行,這個ID也會自增,顯然這個時候插入是順序的。

綜上,根據聚集索引的查詢的確比二級索引要少一次io開銷,使用乙個唯一值的列作為主鍵也未嘗不可。但需要注意的是,如果我們不是用整形這樣的字段作為主鍵時,資料的插入往往不是順序的,這會帶來更大的開銷;在效能上,使用id作為自增主鍵,唯一值的列作為唯一鍵,可能是乙個更好的選擇。把乙個欄位設為唯一鍵或主鍵,再依據這個欄位來進行查詢,中間的差距微乎其微。

6樓:清泉

浪費倒不是啥問題,因為及時你不加,資料庫也會預設生成乙個隱藏的主鍵。

從效能上考慮,業務允許的情況下,能用主鍵索就用主鍵索引。

7樓:Zhu Wiki

一般場景:

採用與業務無關的自增主鍵,保證寫入順序,降低更新聚簇索引的代價,提高寫入效率

高併發寫入場景下:

主鍵上屆成為熱點,自增id併發插入會導致間歇鎖競爭至於上面提到的聚簇索引比輔助索引要少乙個IO,如果你的邏輯索引是針對你查詢的覆蓋索引的話同樣可以避免

8樓:雁南歸

不能說浪費,因為你用邏輯主鍵的情況下,插入的過程中需要定位到頁再插入,效率上會比直接追加到最後乙個資料頁要低很多。

相比之下,輔助索引帶來的多一次的IO的開銷其實並不一定很大,因為一方面Innodb本身有快取,除非全表的隨機掃瞄,否則在大部分業務情況下,訪問基本都是可以命中快取的。另一方面乙個自增有序的主鍵其實在很多業務場景中,比如分頁,排序等都會利用的上。而且innodb表對於主鍵的回盤查找效率是很高的。

我比較傾向於建乙個自增的id做主鍵,再將有業務含義的主鍵字段新增唯一索引的約束。如果可以的話,跨表關聯查詢時使用自增的id做為表關聯的條件,不過這種情況下要對要不要在關聯的表中儲存業務主鍵欄位做個權衡。

9樓:何海山

如果你用隨機主鍵每次插入都要在索引葉里的乙個未知位置插入,無限等於每次插入資料,資料庫就要重做索引。你認為這個開銷對資料庫沒有影響的話我也無話可說……

10樓:Ryou ikonn

1、如果你插入比較少的話實際上是可以忽略建主鍵的開銷的。

2、如果你不需要確認資料的唯一性實際上你應該不需要建這種自增的與業務毫無關聯的主鍵。

3、聚簇索引是比較好,但是提公升效能不到百分之二十,i、如果你想合理的使用到聚集索引你應該考慮到你的業務查詢方式,確保查詢的區域是聚集的,否則無提公升。ii、如果你的業務主鍵是字串,那麼會劣於整形的自增主鍵。更新維護開銷更小,查詢更快。

11樓:韓翔

分情況,開始是業務主鍵,因為伺服器效能差,要優化效能,後來業務複雜度提公升,多數人支援邏輯主鍵,便於控制系統業務的變更帶來的影響,後來網際網路平台成為主流,又回到業務主鍵,優化效能,以後邏輯主鍵還會進一步佔主流,因為擴充套件集群的能力消除了硬體效能瓶頸的制約。

12樓:陳廣勝

一定程度是的。使用邏輯主鍵,是為了避免以後因業務變更而產生的對資料庫設計的影響,效能不是主要的考慮。我以前傾向使用邏輯主鍵,不過現在更支援使用有實際意義的業務主鍵。

為什麼做英語閱讀理解時,我大部分情況下,明明知道每個單詞的意思,可是就是無法準確理解作者的意思呢?

批改高考英語作文 這個很正常,事實是,你還是不理解。這個部分叫閱讀理解,不是單詞識別,對不對!既然知道自己的問題,那需要積累的知識是這個片語合在一起的意思是什麼,加油! 荔枝菌 本人呢自己還是個高中生,所以就以做高考閱讀的經驗回答吧 其實高中的英語閱讀,基本都可以在原文中找到答案。針對你存在的問題,...

教理財是割韭菜?教人理財絕大部分情況下並不能真正讓人變富裕,而是想賺別人的學費錢讓自己變富裕,對嗎?

煥斌 呃.這麼說教理財的機構現階段割韭菜模式比較多但也並非全部無絕對 但本身理財也不能讓人富裕 如果即教會了理財 教學機構也賺到了學費。雙方都達到了目的本質上不衝突 理財是個需要過程知識累積的事情比如說大家能接觸到的理財產品種類繁多管理人也超級多。了解各類產品的屬性就需要具備一定的基礎知識以及理財經...

想不明白,在大部分人想考重點班的情況下,我想去普通班就是異類了。?

淡朗姆 說個親身經歷,以前和我水平差不多甚至記憶力比我好的同學,分班考她在普通班,我在終點班,後來的每次年紀考,我沒下過年紀80,她連前300都沒進 W穩雯 並沒有我身邊就有認識的成績賊好的人可以去重點班但自己選擇去了普通班的人 我朋友她是覺得重點班氛圍太緊張了她希望可以輕鬆一點在普通班同學們也很友...