語法與適用範圍
UPDATE [LOW_PRIORITY] tbl_name SET col1=val1, col2=val2 ... WHERE ...
- 僅對**表級鎖**存儲引擎生效:**MyISAM、MEMORY、CSV、ARCHIVE**。
- **InnoDB(行級鎖)無效**,InnoDB 透過 MVCC 實現讀寫不阻塞,無需此機制。
- 同樣適用於
INSERT、DELETE、REPLACE、LOAD DATA。
MySQL 預設調度策略
- 寫入優先於讀取:寫入請求到達時,若有讀取正在進行,寫入等待讀取結束;但後續新讀取請求會被阻塞在寫入之後(寫入不餓死)。
- 寫入串行化:同一張表同一時間只能有一個寫入者。
- 讀取並行:多個讀取者可同時存取。
LOW_PRIORITY 改變了什麼?
- 寫入者**不再優先於讀取者**。
- 若寫入者正在等待,新來的讀取請求**插隊**在寫入者之前執行。
- 只有當**完全沒有讀取者**時,寫入者才能獲得鎖。
- 理論風險:持續高讀取負載下,
LOW_PRIORITY 寫入可能**無限飢餓**。
對應關鍵字對比
| 關鍵字 | 適用語句 | 效果 | 適用引擎 |
LOW_PRIORITY | INSERT, UPDATE, DELETE, REPLACE, LOAD DATA | 降低寫入優先級,讓讀取優先 | MyISAM, MEMORY |
HIGH_PRIORITY | SELECT, INSERT | 提升讀取/插入優先級,插隊等待中的寫入 | MyISAM, MEMORY |
DELAYED | INSERT, REPLACE | 客戶端立即返回,伺服器排隊批次寫入 | MyISAM, MEMORY |
全域預設調整
[mysqld]
low-priority-updates=1 # 所有支援 LOW_PRIORITY 的語句預設降級
# 單條語句覆蓋:INSERT HIGH_PRIORITY ...
現代架構下的替代方案(更推薦)
- 主從複寫 + 讀寫分離:寫入走主庫,讀取分流至從庫,物理隔離鎖爭用。
- 中間層緩存:Redis/Memcached 承接高頻讀取,降低 MySQL 讀取壓力。
- InnoDB 行級鎖 + MVCC:讀寫不阻塞,根治鎖爭用,首選方案。
- pt-online-schema-change / gh-ost:大表 DDL 時無鎖變更,避免長時間鎖表影響讀寫。
適用場景判斷樹
是否使用 MyISAM/MEMORY?
├─ 否(InnoDB)→ 無需 LOW_PRIORITY,MVCC 已解決讀寫衝突
└─ 是
├─ 讀多寫少、寫入可延遲 → 可用 LOW_PRIORITY 緩解鎖等待
├─ 寫入頻繁、需即時一致性 → 必須遷移至 InnoDB 或架構分離
└─ 批次匯入歷史資料 → 考慮 DELAYED 或離線載入