新聞中心
數據庫分表優(yōu)化:提高性能與可擴展性

隨著互聯網和移動互聯網的迅速發(fā)展,數據量增長的速度也越來越快。對于大型互聯網企業(yè)來說,數據庫性能和可擴展性是業(yè)務發(fā)展的關鍵。然而,在數據量龐大的情況下,單表的數據存儲已經無法滿足業(yè)務需求,數據庫分表優(yōu)化成為了必不可少的一種手段,本文將對數據庫分表的優(yōu)化方案進行探討。
一、什么是數據庫分表
數據庫分表,就是將一個表按照某個規(guī)則,將原本存儲在單張表中的數據分成若干個表進行存儲,從而達到提高數據庫性能和可擴展性的目的。通俗而言,就是在數據庫中創(chuàng)建多個表,以存儲原先一個表中的所有數據。
舉個例子,假設我們有一張“用戶信息表”,包含了所有系統(tǒng)用戶的信息,其中每條記錄包括用戶名、密碼、郵箱等信息。隨著用戶數量的增加,表中的數據量也在不斷增長,導致查詢、更新、刪除等操作變得越來越慢,甚至出現服務器癱瘓的情況。這時,我們可以通過分表來對“用戶信息表”進行優(yōu)化。
二、數據庫分表優(yōu)化的實現方法
實現數據庫分表有多種方法,根據業(yè)務特點,選擇不同的分表方式。
1.按時間分表
如果數據量主要集中在某一段時間內,比如日志信息,可以按照時間將數據分為多個表,以便更快地查詢分析數據。這種分表方式的優(yōu)點是數據查詢和統(tǒng)計非??焖?,缺點是不容易實現跨區(qū)間查詢。
2.按數據類型分表
如果數據是按照某個類型分類的,可以根據分類進行分表,比如商品按照所屬分類進行分表。這種分表方式的優(yōu)點是查詢和統(tǒng)計非??焖伲秉c是增加了表的數量,增加了維護的難度。
3.按ID范圍分表
ID范圍分表是指按照主鍵ID的范圍進行分表,比如將用戶ID為1-100000的記錄存儲在一張表中,將ID為100001-202300的記錄存儲在另一張表中,以此類推。這種分表方式的優(yōu)點是易于擴展、管理,缺點是可能導致查詢性能下降。
4.按hash值分表
按照hash值分表是指根據數據的hash值進行分表,比如將hash值為1-1000的記錄存儲在一張表中,將hash值為1001-2023的記錄存儲在另一張表中,以此類推。這種分表方式的優(yōu)點是易于擴展、管理,查詢性能均衡;缺點是難以完成跨區(qū)間查詢。
三、數據庫分表帶來的好處
1.提高查詢速度
當單表數據量過大時,一次查詢的時間會變得越來越長,通過分表可以降低單表數據量,從而提高查詢速度。
2.提高系統(tǒng)性能
當單表數據量過大時,系統(tǒng)會出現性能瓶頸,甚至崩潰現象。通過分表,可以使數據負載更加均衡,降低單個表的請求量,提高系統(tǒng)的性能。
3.易于擴展
通過分表,可以很容易地添加新的數據節(jié)點,支持系統(tǒng)的線性擴展,為企業(yè)業(yè)務發(fā)展提供了更多的空間。
四、注意事項
1. 多個表之間數據的一致性
在進行分表優(yōu)化之前,應該考慮好多個表之間數據的一致性,確保數據的正確性和完整性。
2. 對索引的合理利用
分表后,數據量變小,可以更精細地設計表的索引,提高查詢性能。
3. 保持分表規(guī)則的一致性
分表規(guī)則一定要保持一致性,不可隨意更改。否則可能導致查詢結果不準確,甚至系統(tǒng)崩潰等問題。
4. 跨表查詢的設計問題
當需要跨表查詢時,設計查詢方式不能簡單地將多張表的結果合并,而應該通過一些復雜的算法進行查詢。
五、
數據庫分表優(yōu)化是一種重要的手段,可以提高數據庫的性能和可擴展性。但是,在進行分表優(yōu)化時,應該考慮好多個表之間的一致性和查詢性能等問題,以保證系統(tǒng)穩(wěn)定和數據正確性。同時,不同的分表方案對應著不同的業(yè)務需求,應該根據實際情況選擇合適的分表方式。
相關問題拓展閱讀:
- 問個mysql優(yōu)化問題
問個mysql優(yōu)化問題
在鍵租謹開始演示之前,我們先介紹下兩個概念。
概念一,數據的可選擇性基數,也就是常說的cardinality值。
查詢優(yōu)化器在生成各種執(zhí)行計劃之前,得先從統(tǒng)計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個字段中的唯一值分布狀態(tài)。
比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這里唯一值越的多少,就是這個列的可選擇基數。
那看到這里我們就明白了,為什么要在基數高的字段上建立索引,而基數低的的字段建立索引反而沒有全表掃描來的快。當然這個只是一方面,至于更深入的探討就不在我這篇探討的范圍了。
概念二,關于HINT的使用。
這里我來說下HINT是什么,在什么時候用。
HINT簡單來說就是在某些特定的場景下人工協(xié)助MySQL優(yōu)化器的工作,使她生成更優(yōu)的執(zhí)行計劃。一般來說,優(yōu)化器的執(zhí)行計劃都是更優(yōu)化的,不過在某些特定場景下,執(zhí)行計劃可能不是更優(yōu)化。
比如:表t1經過大稿基量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執(zhí)行了一條SQL,那么有可能這條SQL的執(zhí)行計劃就不是更優(yōu)的。為什么說有可能呢?
來看下具體演示
譬如,以下兩條SQL,
A:
select * from t1 where f1 = 20;
B:
select * from t1 where f1 = 30;
如果f1的值剛好頻繁更新的值為30,并且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那么對這兩條語句來說,可能不準確的就是B了。
這里順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。
那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。
示例表結構:
mysql> desc t1;+++——+—–++–+| Field | Type| Null | Key | Default | Extra|+++——+—–++–+| id| int(11) | NO | PRI | NULL | auto_increment || rank| int(11) | YES | MUL | NULL | || rank| int(11) | YES | MUL | NULL | || log_time | datetime | YES | MUL | NULL | || prefix_uid | varchar(100) | YES | | NULL | || desc| text| YES | | NULL | || rank| int(11) | YES | MUL | NULL | 型啟|+++——+—–++–+7 rows in set (0.00 sec)
表記錄數:
mysql> select count(*) from t1;++| count(*) |++||++1 row in set (0.01 sec)
這里我們兩條經典的SQL:
SQL C:
select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;
SQL D:
select * from t1 where rank1 =100 and rank2 =100 and rank3 =100;
表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。
那我們來看SQL C的查詢計劃。
顯然,沒有用到任何索引,掃描的行數為32023,cost為3243.65。
mysql> explain format=json select * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “3243.65” }, “table”: { “table_name”: “t1”, “access_type”: “ALL”, “possible_keys”: , “rows_examined_per_scan”: 32023, “rows_produced_per_join”: 115, “filtered”: “0.36”, “cost_info”: {“read_cost”: “3232.07”,”eval_cost”: “11.58”,”prefix_cost”: “3243.65”,”data_read_per_join”: “49K” }, “used_columns”: , “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們加上hint給相同的查詢,再次看看查詢計劃。
這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。
mysql> explain format=json select /*+ index_merge(t1) */ * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “441.09” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: , “key”: “union(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1103, “rows_produced_per_join”: 1103, “filtered”: “100.00”, “cost_info”: {“read_cost”: “330.79”,”eval_cost”: “110.30”,”prefix_cost”: “441.09”,”data_read_per_join”: “473K” }, “used_columns”: , “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們再看下SQL D的計劃:
不加HINT,
mysql> explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “534.34” }, “table”: { “table_name”: “t1”, “access_type”: “ref”, “possible_keys”: , “key”: “idx_rank1”, “used_key_parts”: , “key_length”: “5”, “ref”: , “rows_examined_per_scan”: 555, “rows_produced_per_join”: 0, “filtered”: “0.07”, “cost_info”: {“read_cost”: “478.84”,”eval_cost”: “0.04”,”prefix_cost”: “534.34”,”data_read_per_join”: “176” }, “used_columns”: , “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))” } }}1 row in set, 1 warning (0.00 sec)
加了HINT,
mysql> explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “5.23” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: , “key”: “intersect(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1, “rows_produced_per_join”: 1, “filtered”: “100.00”, “cost_info”: {“read_cost”: “5.13”,”eval_cost”: “0.10”,”prefix_cost”: “5.23”,”data_read_per_join”: “440” }, “used_columns”: , “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))” } }}1 row in set, 1 warning (0.00 sec)
對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。
總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。
在一張有幾百萬個大數據的表中,MySQL的處理引擎會查找得很慢,這時,就必須采用分表甚至分庫的方法。
你可以參考這篇文章:《MySQL大數據處理》
摘錄如下:
一、概述
分表是個目前算是比較炒的比較流行的概念,特別是在大負載的情況下,分表是一個良好分散數據庫壓力的好方法。
首先要了解為什么要分表,分表的好處是什么。我們先來大概了解以下一個數據庫執(zhí)行SQL的過程:
接收到SQL –> 放入SQL執(zhí)行隊列 –> 使用分析器分解SQL –> 按照分析結果進行數據的提取或者修改 –> 返回處理結果
當然,這個流程圖不一定正確,殲明唯這只是我自己主觀意識上這么我認為。那么這個處理過程當中,最容易出現問題的是什么?就是說,如果前一個SQL沒
有執(zhí)行完畢的話,后面的SQL是不會執(zhí)行的,因為為了保證數據的完整性,必須對數據表文件進行鎖定,包括共享鎖和獨享鎖兩種鎖定。共享鎖是在鎖定的期間,
其它線程也可以訪問這個數據文件,但是不允許修改操作,相應的,獨享鎖就是整個文件就是歸一個線程所有,其它線程無法訪問這個數據文件。一般MySQL中
最快的存儲引擎MyISAM,它是基于表鎖定的,就是說如果一鎖定的話,那么整個數據文件外部都無法訪問,必須等前一個操作完成后,才能接收下一個操作,
那么在這個前一個操作沒有執(zhí)行完成,后一個操作等待在隊列里無法執(zhí)行的情況叫做阻塞,一般我們通俗意義上叫做“鎖表”。
鎖表直接導致的后果是什么?就是大量的SQL無法立即執(zhí)行,必須等隊列前面的SQL全部執(zhí)行完畢才能繼續(xù)執(zhí)行。這個無法執(zhí)行的SQL就會導致沒有結果,或者延遲嚴重,影響用戶體驗。
特別是對于一些使用比較頻繁的表,比如SNS系統(tǒng)中的用戶信息表、論壇系統(tǒng)中的帖子表等等,都是訪問量大很大的表,為了保證數據的快速提取返回給用戶,必須使用一些處理方式來解決這個問題,這個就是我今天要聊到的分表技術。
分表技術顧名思義,就是把若干個存儲相同類型數據的表分成幾個表分表存儲,在提取數據的時候,不同的用戶訪問不同的表,互不沖突,減少鎖表的幾
率。比如,目前保存用戶分表有兩個表,一個是user_1表,還有一個是 user_2 表,兩個表保存了不同的用戶信息,user_1
保存了前10萬的用戶信息,user_2保存了后10萬名用戶的信息,現在如果同時查詢用戶 heiyeluren1 和 heiyeluren2
這個兩個用戶,那么就是分表從不同的表提取出來,減少鎖表的可能。
我下面要講述的兩種分表方法我自己都沒有實驗過,不保證準確能用,只是提供一個設計思路。下面關于分表的例子我假設是在一個貼吧系統(tǒng)的基礎上來進行處理和構建的。(如果沒有用過貼吧的用戶趕緊Google一下)
二、基于基礎表的分表處理
這個基于基槐穗礎表的分表處理方式大致的思想就是:一個主要表,保存了所有的基本信息,如果某個項目需要找到它所存儲的表,那么必須從這個基礎表中
查找出對應的表名等項目,好直接訪問這個表。如果覺得這個基礎表速度不夠快,可以完全把整個基礎表保存在緩存或者內存中,方便有效的查詢。
我們基于貼吧的情況,構建假設如下的3張表:
1. 貼吧版塊表: 保存貼吧中版塊的信息
2. 貼吧主題表:保存貼吧中版塊中的主題信息,用于瀏覽
3. 貼吧回復表:保存主題的原始內容和回復內容
“貼吧版塊表”包含如下字段:
版塊IDboard_idint(10)
版塊名稱 board_name char(50)
子表IDtable_idallint(5)
產生時間 createddatetime
“貼吧主題表”包含如下字段:
主題IDtopic_idint(10)
主題名稱topic_name char(255)
版塊IDboard_idint(10)
創(chuàng)建時間createddatetime
“貼吧回復表”的字段如下:
回復IDreply_idint(10)
回復內容 reply_texttext
主題IDtopic_idint(10)
版塊ID氏培 board_idint(10)
創(chuàng)建時間 createddatetime
那么上面保存了我們整個貼吧中的表結構信息,三個表對應的關系是:
版塊 –> 多個主題
主題 –> 多個回復
那么就是說,表文件大小的關系是:
版塊表文件
所以基本可以確定需要對主題表和回復表進行分表,已增加我們數據檢索查詢更改時候的速度和性能。
看了上面的表結構,會明顯發(fā)現,在“版塊表”中保存了一個”table_id”字段,這個字段就是用于保存一個版塊對應的主題和回復都是分表保存在什么表里的。
比如我們有一個叫做“PHP”的貼吧,board_id是1,子表ID也是1,那么這條記錄就是:
board_id | board_name | table_id | created
1 | PHP | 1 |:30:12
相應的,如果我需要提取“PHP”吧里的所有主題,那么就必須按照表里保存的table_id來組合一個存儲了主題的表名稱,比如我們主題表的前綴是“topic_”,那么組合出來“PHP”吧對應的主題表應該是:“topic_1”,那么我們執(zhí)行:
SELECT * FROM topic_1 WHERE board_id = 1 ORDER BY topic_id DESC LIMIT 10
這樣就能夠獲取這個主題下面回復列表,方便我們進行查看,如果需要查看某個主題下面的回復,我們可以繼續(xù)使用版塊表中保存的“table_id”來進行查詢。比如我們回復表的前綴是“reply_”,那么就可以組合出“PHP”吧的ID為1的主題的回復:
SELECT * FROM reply_1 WHERE topic_id = 1 ORDER BY reply_id DESC LIMIT 10
這里,我們能夠清晰的看到,其實我們這里使用了基礎表,基礎表就是我們的版塊表。那么相應的,肯定會說:基礎表的數據量大了以后如何保證它的速度和效率?
當然,我們就必須使得這個基礎表保持更好的速度和性能,比如,可以采用MySQL的內存表來存儲,或者保存在內存當中,比如Memcache之類的內存緩存等等,可以按照實際情況來進行調整。
一般基于基礎表的分表機制在SNS、交友、論壇等Web2.0網站中是個比較不錯的解決方案,在這些網站中,完全可以單獨使用一個表來來保存基本標識和目標表之間的關系。使用表保存對應關系的好處是以后擴展非常方便,只需要增加一個表記錄。
【優(yōu)勢】增加刪除節(jié)點非常方便,為后期升級維護帶來很大便利
【劣勢】需要增加表或者對某一個表進行操作,還是無法離開數據庫,會產生瓶頸
三、基于Hash算法的分表處理
我們知道Hash表就是通過某個特殊的Hash算法計算出的一個值,這個值必須是惟一的,并且能夠使用這個計算出來的值查找到需要的值,這個叫做哈希表。
我們在分表里的hash算法跟這個思想類似:通過一個原始目標的ID或者名稱通過一定的hash算法計算出數據存儲表的表名,然后訪問相應的表。
繼續(xù)拿上面的貼吧來說,每個貼吧有版塊名稱和版塊ID,那么這兩項值是固定的,并且是惟一的,那么我們就可以考慮通過對這兩項值中的一項進行一些運算得出一個目標表的名稱。
現在假如我們針對我們這個貼吧系統(tǒng),假設系統(tǒng)更大允許1億條數據,考慮每個表保存100萬條記錄,那么整個系統(tǒng)就不超過100個表就能夠容納。按照這個標準,我們假設在貼吧的版塊ID上進行hash,獲得一個key值,這個值就是我們的表名,然后訪問相應的表。
我們構造一個簡單的hash算法:
function get_hash($id){
$str = bin2hex($id);
$hash = substr($str, 0, 4);
if (strlen($hash)
$hash = str_pad($hash, 4, “0”);
}
return $hash;
}
算法大致就是傳入一個版塊ID值,然后函數返回一個4位的字符串,如果字符串長度不夠,使用0進行補全。
比如:get_hash(1),輸出的結果是“3100”,輸入:get_hash(23819),得到的結果是:3233,那么我們經過簡單的跟表前綴組合,就能夠訪問這個表了。那么我們需要訪問ID為1的內容時候哦,組合的表將是:topic_3100、reply_3100,那么就可以直接對目標表進行訪問了。
當然,使用hash算法后,有部分數據是可能在同一個表的,這一點跟hash表不同,hash表是盡量解決沖突,我們這里不需要,當然同樣需要預測和分析表數據可能保存的表名。
如果需要存儲的數據更多,同樣的,可以對版塊的名字進行hash操作,比如也是上面的二進制轉換成十六進制,因為漢字比數字和字母要多很多,那么重復幾率更小,但是可能組合成的表就更多了,相應就必須考慮一些其它的問題。
歸根結底,使用hash方式的話必須選擇一個好的hash算法,才能生成更多的表,然數據查詢的更迅速。
【優(yōu)點hash算法直接得出目標表名稱,效率很高】通過
【劣勢】擴展性比較差,選擇了一個hash算法,定義了多少數據量,以后只能在這個數據量上跑,不能超過過這個數據量,可擴展性稍差
四、其它問題
1. 搜索問題
現在我們已經進行分表了,那么就無法直接對表進行搜索,因為你無法對可能系統(tǒng)中已經存在的幾十或者幾百個表進行檢索,所以搜索必須借助第三方的組件來進行,比如Lucene作為站內搜索引擎是個不錯的選擇。
2. 表文件問題
我們知道MySQL的MyISAM引擎每個表都會生成三個文件,*.frm、*.MYD、*.MYI
三個文件,分表用來保存表結構、表數據和表索引。Linux下面每個目錄下的文件數量更好不要超過1000個,不然檢索數據將更慢,那么每個表都會生成三
個文件,相應的如果分表超過300個表,那么將檢索非常慢,所以這時候就必須再進行分,比如在進行數據庫的分離。
使用基礎表,我們可以新增加一個字段,用來保存這個表保存在什么數據。使用Hash的方式,我們必須截取hash值中第幾位來作為數據庫的名字。這樣,完好的解決這個問題。
五、總結
在大負載應用當中,數據庫一直是個很重要的瓶頸,必須要突破,本文講解了兩種分表的方式,希望對很多人能夠有啟發(fā)的作用。當然,本文代碼和設想沒有經過任何代碼測試,所以無法保證設計的完全準確實用,具體還是需要讀者在使用過程當中認真分析實施。
數據庫優(yōu)化的問題需要從多個角度考慮:
一、針對數據庫結構和查詢的優(yōu)化:
在一般的應用中,合理的數據表結構和索引的設計,能夠更大化螞棗查詢性能。即時在千萬級別的數據表中,針對主鍵的查詢也會非??焖佟T跀祿刻蟮那闆r下,沒有使用索引的查詢可能會非常緩慢。where條件會用到的字段中,要盡量都加上索引。模糊查詢可以通過全文索引來優(yōu)化。另外,單條記錄的長短也會對查詢速率產生一定的影響(記錄越長,磁盤讀取數據時需要移動的距離就越長)。一些關鍵的數據更好放在小表中。存儲引擎的選擇也很重要。MYISAM引擎的查詢性能更好,而且支持全文索引。MYISAM的索引是壓縮存儲的,可以節(jié)約磁盤空間。更重要的時,它可以將更多的索引加載到內存中,大大提畢碰高查詢效率。
二、針對架構的優(yōu)化:
在高并發(fā)的應用中,僅僅針對數據庫層面的優(yōu)化已經力不從心。數據庫的能力是有限的,更優(yōu)秀的數據庫也存在性能瓶頸。大量的并發(fā)查詢將導致數據悶數拆庫不堪重負。主從庫、讀寫分離是常見的優(yōu)化方式。對于一些經常訪問的熱數據,每次都執(zhí)行數據庫查詢會造成資源浪費,而且非常低效。如果將這些熱的數據以key-value(鍵和值)的方式存儲在內存中,可以更大化性能。
一些熱門的應用,如你提到的微博,除了做好數據庫方面的優(yōu)化外,架構優(yōu)化非常關鍵。本例中,可以為每個用戶單獨存儲好友的最新微博。在用戶發(fā)布微博時,將這條微博的ID存儲在所有好友的“最新微博”中。數據滿30條時,同時刪除舊的數據。這樣在獲取好友最新微博時,不需要查詢數據庫,效率非常高。
數據庫分表優(yōu)化的介紹就聊到這里吧,感謝你花時間閱讀本站內容,更多關于數據庫分表優(yōu)化,「數據庫分表優(yōu)化」:提高性能與可擴展性,問個mysql優(yōu)化問題的信息別忘了在本站進行查找喔。
香港服務器選創(chuàng)新互聯,2H2G首月10元開通。
創(chuàng)新互聯(www.cdcxhl.com)互聯網服務提供商,擁有超過10年的服務器租用、服務器托管、云服務器、虛擬主機、網站系統(tǒng)開發(fā)經驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務器、香港云服務器、免備案服務器等。
分享題目:「數據庫分表優(yōu)化」:提高性能與可擴展性(數據庫分表優(yōu)化)
網頁路徑:http://m.fisionsoft.com.cn/article/dhhcoid.html


咨詢
建站咨詢
