對 MySQL 表分割槽與 MERGE分表的個人理解

2021-10-07 01:30:37 字數 3654 閱讀 2027

最近資料庫表資料接近3000萬,查詢效能有點慢

對於mysql資料庫我已經做的:

那為什麼還慢呢?排查發現,雖然分了區,但是有乙個常用的查詢語句,預設並沒有帶時間戳這個字段,分割槽是按時間戳來劃分的,你又不帶時間戳這個字段,那不就得全分割槽檢索了嗎?所以慢啊,分割槽並沒有被有效利用。

就好像網上看到的一些例子,用日期分割槽後,想測試一下效能:

select

count(*

)from mytable;

select

*from mytable where user_id =

34;

效果並不明顯……廢話,你查全部資料,並沒有使用時間戳來篩選,當然是全分割槽檢索了。

我認為表分割槽和程式語言裡中的字典/map是相似的,按某種規則建立起乙個個存放資料桶,資料按照你給定的規則放進不同的桶裡。依據關鍵字來確定資料在哪個桶裡,這樣就一下子過濾掉了大部分無效資料。在我的例子裡,時間戳就是這個關鍵字,如果你不帶這個關鍵字,那就和未分割槽一樣,還是要在全部分割槽裡查詢。

alter

table mytable

drop

primary

key,

addprimary

key(

`id`

,`device_id`

)partition

by list (device_id %20)

(partition p0 valuesin(

1)engine

=innodb

,partition p1 valuesin(

2)engine

=innodb

,partition p2 valuesin(

3)engine

=innodb

,partition p3 valuesin(

4)engine

=innodb

,partition p4 valuesin(

5)engine

=innodb

,partition p5 valuesin(

6)engine

=innodb

,partition p6 valuesin(

7)engine

=innodb

,partition p7 valuesin(

8)engine

=innodb

,partition p8 valuesin(

9)engine

=innodb

,partition p9 valuesin(

10)engine

=innodb

,partition p10 valuesin(

11)engine

=innodb

,partition p11 valuesin(

12)engine

=innodb

,partition p12 valuesin(

13)engine

=innodb

,partition p13 valuesin(

14)engine

=innodb

,partition p14 valuesin(

15)engine

=innodb

,partition p15 valuesin(

16)engine

=innodb

,partition p16 valuesin(

17)engine

=innodb

,partition p17 valuesin(

18)engine

=innodb

,partition p18 valuesin(

19)engine

=innodb

,partition p19 valuesin(

0)engine

=innodb

);

這樣就可以每次查詢的時候,先按分割槽規則定位到分割槽,只在分割槽中檢索資料了,很快。

merge 分表

在學習過程中,也看到了 merge 分表的方法。

看到有人說 merge 分表比較簡單,應用程式無需改動,只要操作總表即可。

是這樣的,插入是沒問題,但如果查詢仍然操作總表的話,是不會提公升效能的,因為還是要檢索所有子表內的資料。

所以merge拆表,應該主要是做資料拆分,如果要提公升查詢效能,還是要改程式,直接定位要查詢的子表,才能快。比較適合按日期劃分子表的場景吧。

我想它的優點應該是靈活:

表分割槽表分割槽是真正的對上層應用程式**,不需要改動程式。

查詢時帶上關鍵字字段,大大縮小查詢範圍。我覺得它的缺點是不靈活:

insert

into mytable_new select

*from mytable where id >=

1and id <

1000000

;

轉移成功後,再把新錶、舊表重新命名一下,就完成了表替換。

rename

table mytable to mytable_old;

rename

table mytable_new to mytable;

可以用 explain 來確認查詢的分割槽

explain

select

*from mytable where device_id =

36;

即使直接使用id進行查詢,加上關鍵字字段,也能縮小查詢範圍

explain

select

*from mytable where id =

3672

and device_id =

36;

上面如果不帶device_id,只帶id查詢,也很快,但仍然是在所有分割槽檢索。帶上device_id就直接定位到了乙個分割槽,更快。

如果查詢條件中沒帶device_id,那分割槽就根本沒有被利用到了。下面語句會在所有分割槽中篩選資料

select

*from mytable where class_id =

32and ts between

1593234321

and1594526324

;

所以表分割槽後,上層應用程式查詢時,也要使用關鍵字字段,使分割槽能夠有效

對於提公升查詢效能:

其實表分割槽就是資料庫按既定規則幫你定位分割槽,縮小了查詢範圍。

而 merge 分表需要你在應用程式層面,按規則定位到子表,縮小查詢範圍。

對資料庫的優化不只是資料庫,還要『優化』使用它的人。資料庫優化好了,某乙個開發人員寫了乙個sql語句,索引全部未命中,分割槽條件欄位未使用……那好了,就是全表掃瞄,對於大表的查詢sql,還是要仔細斟酌,了解表結構、索引設計才能有好的效率,避免全表掃瞄。

mysql 分表,分割槽,分庫相關及merge引擎

為什麼要分表和分割槽?日常開發中我們經常會遇到大表的情況,所謂的大表是指儲存了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致資料庫在查詢和插入的時候耗時太長,效能低下,如果涉及聯合查詢的情況,效能會更加糟糕。分表和表分割槽的目的就是減少資料庫的負擔,提高資料庫的效率,通常點來講就是提高表的增刪改...

mysql分表與分割槽

1 首先得確認mysql是否支援分割槽功能,這可以通過命令 show plugins 檢視如果顯示如下,則說明你的mysql版本支援partition 2 innodb一般用於具有事務和外來鍵的場合,它預設將所有的表資料和索引檔案放在乙個名為ibdata1的檔案中,屬於共享表空間。myisam預設每...

Mysql的merge表型別

將多個表在邏輯上當作乙個表 建立後有兩個檔案,frm 表結構定義 mrg union表的名字清單 兩個基本表 create table merge 1 id int 5 not null,name varchar 100 not null,primary key id create table me...