場(chǎng)景——MYSQL
一、MYSQL 億級(jí)表新增字段怎么弄?
1 優(yōu)先方案:MySQL8.0 Instant 算法(秒級(jí)完成)。
適用條件:
MySQL版本≥8.0.12
新增字段位于所有列的最后(不支持字段中間插入)
表非壓縮格式(ROW FORMAT≠COMPRESSED)
無(wú)全文索引/FTS表
2 其他方案(Mysql版本低于8):
- pt-OSC工具
- 新增一張同結(jié)構(gòu)的臨時(shí)表,加新字段,再把億級(jí)數(shù)據(jù)導(dǎo)過(guò)去。最后改名替換原表(Rename table A to A_old, A_new to A;)
二、分庫(kù)分表后查詢性能暴跌怎么辦?
場(chǎng)景:對(duì)訂單表拆分,通過(guò) user_id % 1024 將數(shù)據(jù)分散到 1024 個(gè)分片,現(xiàn)在要根據(jù) order_id 查詢。
卡點(diǎn):
- 當(dāng) WHERE 條件攜帶 user_id 時(shí),可精準(zhǔn)定位分片(如 user_id=101 → 分片 101%1024=101);
- 當(dāng)僅按 order_id 查詢時(shí),需遍歷全部 1024 個(gè)分片,導(dǎo)致查詢性能暴跌;
方案:
- 冗余全表法:存儲(chǔ)兩份數(shù)據(jù) → 分別按 user_id 和 order_id 分片;
缺點(diǎn):存儲(chǔ)翻倍、數(shù)據(jù)一致性難解決; - 索引表法:只創(chuàng)建一個(gè)包含 user_id 和 order_id 的索引表,在插入訂單時(shí)再插入一條數(shù)據(jù)到索引表中,查詢時(shí)先去索引表根據(jù) order_id 獲取 user_id,再去對(duì)應(yīng)分片查詢;
缺點(diǎn):查詢延時(shí)(要先查索引表)、隨著數(shù)據(jù)量變大,索引表可能也要分片; - 基因分片法:將分片路由信息嵌入業(yè)務(wù)ID,通過(guò)在雪花算法生成的ID中植入“分片基因”,使任何ID都自帶位置信息;(order_id 中包含 user_id 的基因)
三、MYSQL 海量數(shù)據(jù)的分頁(yè)查詢優(yōu)化,如果主鍵是分布式ID?
場(chǎng)景:使用 select ... limit offset,size,分頁(yè)在大數(shù)據(jù)量下存在性能瓶頸。
分析:
- 數(shù)據(jù)偏移(Offset過(guò)大):MySQL需掃描前 offset 條記錄并丟棄,(如 LIMIT 10000,10 需掃描 10010 行),導(dǎo)致 I/0 和CPU資源浪費(fèi);
- 內(nèi)存占用過(guò)高:全結(jié)果集加載到內(nèi)存再截取,可能觸發(fā)OOM(OutofMemory);
- 回表開(kāi)銷(xiāo):若未覆蓋索引,需回表查詢完整數(shù)據(jù),產(chǎn)生隨機(jī)I/O;
- COUNT(*)效率低:統(tǒng)計(jì)總數(shù)需全表掃描,加劇性能問(wèn)題;
單機(jī)方案:
1 游標(biāo)分頁(yè):
- 原理:記錄上一頁(yè)最后一條記錄的ID(或時(shí)間戳),基于有序字段定位下一頁(yè)起始位置;
- 要求:排序字段需唯一旦連續(xù)(如自增主鍵或時(shí)間戳),必須建立索引;
2 延遲關(guān)聯(lián):
- 原理:先通過(guò)覆蓋索引獲取主鍵,再關(guān)聯(lián)原表減少回表次數(shù);
- 場(chǎng)景:非主鍵排序,深分頁(yè);
3 覆蓋索引:
- 原理:索引包含查詢所需所有字段,無(wú)需回表;
- 要求:查詢字段必須全在索引中;
4 主鍵范圍分頁(yè):
- 原理:利用主鍵連續(xù)性分塊查詢(需ID連續(xù)無(wú)空洞);
- 缺點(diǎn):數(shù)據(jù)刪除影響ID連續(xù)性;
5 業(yè)務(wù)層優(yōu)化:
- 緩存總數(shù):避免重復(fù)執(zhí)行cOUNT(*);
- 用 Redis 緩存總行數(shù)限制頁(yè)數(shù):如百度僅展示79頁(yè),避免深分頁(yè);
- 預(yù)加載策略:熱門(mén)數(shù)據(jù)預(yù)加載到緩存;
分布式方案:
1 基于分布式ID的范圍查詢:
- 場(chǎng)景:排序字段為分布式ID(如Snowflake生成的主鍵);
- 優(yōu)勢(shì):各分片并行查詢,無(wú)需全局聚合;
2 全局二級(jí)索引:
- 原理:在分布式數(shù)據(jù)庫(kù)(如PolarDB-X)中創(chuàng)建跨分片索引,統(tǒng)一排序字段;
3 ES輔助查詢:
- 流程:
- 寫(xiě)數(shù)據(jù)時(shí)同步到 ES (含主鍵和排序字段);
- 分頁(yè)查詢由 ES 返回主鍵列表;
- 用主鍵批量查詢數(shù)據(jù)庫(kù)獲取明細(xì);
- 優(yōu)勢(shì):ES擅長(zhǎng)排序分頁(yè);
4 分頁(yè)中間件:
- 工具:ShardingSphere支持跨庫(kù)分頁(yè)路由;
四、如何優(yōu)化Mysql頻繁全表掃描的查詢性能?
原因:
- 消耗大量磁盤(pán)I/0:對(duì)于大表來(lái)說(shuō),讀取整張表的數(shù)據(jù)可能需要大量的磁盤(pán)讀取操作;
- 占用內(nèi)存資源:即使MYSQL采用“邊讀邊發(fā)”的策略,但在某些情況下,仍需要將部分或全部結(jié)果集保存到內(nèi)存中;
- 降低系統(tǒng)響應(yīng)速度:全表掃描會(huì)導(dǎo)致查詢響應(yīng)時(shí)間變長(zhǎng),進(jìn)而影響用戶體驗(yàn)和其他業(yè)務(wù)的正常運(yùn)行;
解決方案:
| 索引優(yōu)化:讓數(shù)據(jù)查找更高效 |
|
| 分區(qū)表:減少掃描范圍 |
|
| 查詢優(yōu)化:減少查詢開(kāi)銷(xiāo) |
|
| 數(shù)據(jù)歸檔與清理:減少數(shù)據(jù)膨脹 |
|
| 硬件與配置優(yōu)化:提升底層性能 |
|
| 架構(gòu)優(yōu)化:分布式與負(fù)載均衡 |
|
五、干萬(wàn)級(jí)大表如何快速刪除大量數(shù)據(jù)
1. 分批次刪除(最通用)
2. 分區(qū)表刪除(提前設(shè)計(jì))
3. TRUNCATE TABLE(刪全表)
4. 新表遷移法(保留少量數(shù)據(jù))
5. 工具輔助(如 pt-archiver)
六、

浙公網(wǎng)安備 33010602011771號(hào)