MySQL高階特性之分割槽表

2022-08-18 23:21:18 字數 2623 閱讀 6164

對於使用者而言,分割槽表是乙個獨立的邏輯表,但是在底層由多個物理子表組成。實現分割槽的**實際上是對一組底層表的控制代碼物件的封裝,對分割槽表的請求都會通過控制代碼物件轉化成對儲存引擎的介面呼叫

mysql在建立表的時候可以通過使用partition by子句定義每個分割槽存放的資料。在執行查詢的時候,優化器根據分割槽定義過濾那些沒有我們需要的資料的分割槽,這樣查詢就可以無需掃瞄所有分割槽——只需要查詢包含需要資料的分割槽即可。

分割槽的乙個主要目的是將資料按照乙個較粗的粒度分別存放在不同的表中。這樣做可以將相關的資料存放在一起,另外,當我們想要一次批量刪除整個分割槽的資料也會變得很方便。

在以下的場景中,分割槽可以起到很大的作用:

分割槽表本身也有一些限制,下面幾點尤為重要:

儲存引擎管理分割槽的各個底層表和管理普通表並沒有什麼區別(所有的底層表都必須使用相同的儲存引擎)

,分割槽表的索引只是在各個底層表上各自加上乙個完全相同的索引。從儲存引擎的角度看,底層表和乙個普通表並沒有什麼區別,儲存引擎也無需知道這是乙個普通表還是乙個分割槽表的一部分。

分割槽表上的操作按照下面的操作邏輯進行:

select 查詢

當查詢乙個分割槽表的時候,分割槽層先開啟並鎖住所有的底層表,優化器先判斷是否可以過濾部分分割槽,然後再呼叫對應的儲存引擎介面訪問各個分割槽的資料

insert 操作

當寫入一條記錄的的時候,分割槽層先開啟並鎖住所有的底層表,然後確定哪個分割槽接收這條記錄,再將記錄寫入對應底層表

delete 操作

當刪除一條記錄的的時候,分割槽層先開啟並鎖住所有的底層表,然後確定資料對應的分割槽,最後對相應底層表進行刪除操作

update 操作

當更新一條記錄時,分割槽層先開啟並鎖住所有的底層表,mysql先確定需要更新的記錄再哪個分割槽,然後取出資料並更新,再判斷更新後的資料應該放在哪個分割槽,最後對底層表進行寫入操作,並對原資料所在的底層表進行刪除操作。

這些操作都是支援過濾的。

雖然每個操作都會「先開啟並鎖住所有的底層表」, 但這並不是說分割槽表在處理過程中是鎖住全表的。如果儲存引擎能夠自己實現行級鎖,則會在分割槽層釋放對應表鎖。這個加鎖和解鎖過程與普通innodb上的查詢類似。

mysql支援多種分割槽表,我們看到最多的就是根據範圍進行分割槽,每個分割槽儲存落在某個範圍內的記錄。分割槽表示式可以是列,也可以是包含列的表示式。

例如,如下表就將每一年的銷售額都存放在不同的分割槽中:

create table sales(

order_date datetime not null,

....

)engine=innodb partition by range(year(order_date))(

partition p_2010 values less than (2010),

partition p_2011 values less than (2011),

partition p_2012 values less than (2012),

partition p_catchall values less than maxvalue;

)

partition 分割槽子句中可以使用各種函式。但是有乙個要求,表示式返回的值必須是乙個確定的整數,且不能是乙個常數。

mysql還支援鍵值、雜湊和列表分割槽等。

如果我們希望從乙個非常大的表中查詢出一段時間的記錄,我們應該如何查詢這個表,如何才能更加高效?

因為資料量非常大,肯定不能在每次查詢的時候都掃瞄全表,考慮到索引在空間和維護上的消耗,我們也不希望使用索引。即使真的使用索引,也會發現資料並不是按照想要的方式進行聚集,會產生大量的碎片,最終導致乙個查詢產生成千上萬的隨機i/o。而事實上,當資料量超級大時,b-tree索引就已經無法祈禱作用了。

因此我們可以選擇一些更粗粒度但消耗更少的方式檢索資料,例如在大量的資料上只索引對應的一小塊元資料。

這正是分割槽要做的事情,理解分割槽可以將其當作索引的最初形態。因為分割槽無需額外的資料結構記錄每個分割槽有哪些資料——分割槽不需要精確定位每條資料的位置,也就無須額外的資料結構——所以其代價非常低。只需要乙個簡單的表示式就可以表達每個分割槽存放的是什麼資料。

為了保證大資料量的可擴充套件性,一般有以下兩個策略:

全量掃瞄資料,不需要任何索引:只要能夠使用 where 條件,將需要的資料限制在少數分割槽中,則效率是很高的。使用這種策略假設不用將資料完全放入記憶體中,同時還假設需要的資料全部都在磁碟上。因為記憶體相對較小,資料很快會被擠出記憶體,所以快取起不了任何作用。這個策略適用於以正常的方式訪問大量資料的時候。

索引資料,並分離熱點:如果資料有明顯的「熱點」,而且除了這部分資料,其他資料很少被訪問到,那麼可以將這部分熱點資料單獨放在乙個分割槽中,讓這個分割槽的資料可以有機會都快取在記憶體中。這樣的查詢可以只訪問乙個很小的分割槽表,能夠使用索引,也能夠有效的使用快取。

上面介紹的兩個分割槽策略都基於兩個非常重要的假設:查詢都能夠過濾掉很多額外的分割槽、分割槽本身並不會帶來很多額外的代價。

事實證明,這兩個假設在某些場景下會有問題:

Postgresql之分割槽表

參考 建立步驟 注意 以下針對10.0版本之前的用法,新版本見 1 建立主表。不用為該錶定義任何檢查限制,除非需要將該限制應用到所有的分割槽表中。同樣也無需為該錶建立任何索引和唯一限制。create table almart date key date,hour key smallint,clien...

MySQL分割槽表

分割槽表是一種粗粒度,簡易的索引策略,適用於大資料的過濾場景.最適合的場景是,沒有合適的索引時,對其中幾個分割槽表進行全表掃瞄.或者只有乙個分割槽表和索引是熱點,而且這個分割槽和索引能夠全部儲存在記憶體中.限制單錶分割槽數不要超過150個,並且注意某些導致無法做分割槽過濾的細節,分割槽表對於單條記錄...

mysql分割槽表

對使用者來說,分割槽表是乙個獨立的邏輯表,但是底層由多個物理子表組成。實現分割槽的 實際上是對一組底層表的控制代碼物件的封裝。mysql在建立表時使用partition by子句定義每個分割槽存放的資料。在執行查詢的時候,優化器會根據分割槽定義過濾那些沒有我們需要資料的分割槽,這樣查詢就無須掃瞄所有...