建立乙個表t:
create table `t` (插入的兩行記錄分別落在p_2018和p_2019這兩個分割槽上。`ftime` datetime not null,
`c` int(11) default null,
key (`ftime`)
) engine=innodb default charset=latin1
partition by range (year(ftime))
(partition p_2017 values less than (2017) engine = innodb,
partition p_2018 values less than (2018) engine = innodb,
partition p_2019 values less than (2019) engine = innodb,
partition p_others values less than maxvalue engine = innodb);
insert into t values('2017-4-1',1),('2018-4-1',1);
這個表包含乙個.frm檔案和4個.ibd檔案,每個分割槽對應乙個.ibd檔案:
每當第一次訪問乙個分割槽表的時候,mysql需要把所有的分割槽都訪問一遍。乙個典型的報錯情況是這樣的:如果乙個分割槽表的分割槽很多,比如超過了1000個,而mysql啟動的時候,open_files_limit引數使用的是預設值1024,那麼就會在訪問這個表的時候,由於需要開啟所有的檔案,導致開啟表檔案的個數超過了上限而報錯。
從mysql 5.7.9開始,innodb引擎引入了本地分割槽策略,這個策略是在innodb內部自己管理開啟分割槽的行為。
從mysql 8.0版本開始,就不允許建立myisam分割槽表了,只允許建立已經實現了本地分割槽策略的引擎。
目前來看,只有innodb和ndb這兩個引擎支援了本地分割槽策略。
從server層看的話,乙個分割槽表就只是乙個表。
雖然只操作乙個分割槽,但是會持有整個表t的mdl鎖。
小結:mysql在第一次開啟分割槽表的時候,需要訪問所有的分割槽;
在server層,認為這是同一張表,因此所有分割槽公用乙個mdl鎖;
在引擎層,認為這是不同的表,因此mdl鎖之後執行過程,會根據分割槽表規則,只訪問必要的分割槽。
分割槽表優勢是對業務透明,對業務來說。使用分割槽表的業務**更簡潔。
分割槽表可以很方便的清理歷史資料,按照時間分割槽的分割槽表,可以直接通過alter table t drop partition... 這個語法刪掉分割槽,從而刪掉過期的歷史資料。
alter table t drop partition...操作是直接刪除分割槽檔案,效果跟drop普通表類似。與使用delete語句刪除資料相比,優勢是速度快,對系統影響小。
mysql除了上面說的以範圍分割槽外,還支援hash分割槽、list分割槽等分割槽方法。
實際使用的時候,分割槽表跟使用者分表比起來,有兩個繞不開的問題:乙個是第一次訪問的時候需要訪問所有分割槽,另乙個是共用mdl鎖。
因此,如果使用分割槽表,就不要建立太多的分割槽。
分割槽並不是越細越好。事實上,單錶或者單分割槽的資料一千萬行,只要沒有特別大的索引,對於現在的硬體能力來說算是小表。
分割槽也不要提前預留太多,使用之前預先建立即可。
比如查詢需要跨多個分割槽取資料,查詢效能就會比較慢,基本上就不是分割槽表本身的問題,而是資料量的問題或者說是使用方式的問題了。
到底要不要使用儲存過程?
mysql 執行語句是要先編譯,然後再執行的。這樣如果查詢併發大的時候。會浪費很多資源和時間。造成mysql程序占用資源過多,症狀就是慢。但儲存過程可以把一些特別的語句封裝成乙個方法 再編譯好成乙個可以執行的方法,對外只要接收引數就可以了。這樣就不用再編譯。執行就快了。什麼時候會用到?你覺得你資料庫...
除非必要,不要使用Linux訊號
除非必要,不要使用linux的訊號做任何事情。因為這套工具的使用非常容易出錯,對開發人員的基礎知識和經驗要求較高。除非必要,不要處理sigse 處理錯誤會導致程序段錯誤後進入處理段錯誤的死迴圈。除非必要,不要處理sigchld。處理錯誤會產生殭屍程序。除非必要,不要處理sigcont。systemd...
分割槽依據欄位要不要再建索引
分割槽依據欄位要不要再建索引呢?要的。雖然表已經根據此欄位分割槽,但這不能等同於索引。分了區,只能說該字段為某個值的記錄會在某個分割槽裡面,但不是索引,還要一頓好找。有時候,主鍵不等於分割槽依據列,這時候主鍵又想建聚集索引的話,那麼必須包含分割槽依據列,搞成復合主鍵。那麼,這種情況下,分割槽依據列不...