WHERE、ORDER BY 列必須建索引。IS NULL 判斷:導致索引失效。設置默認值 0,改 WHERE num=0。!=/<>:導致全表掃描,改用 IN/UNION ALL。OR 連接條件:導致索引失效。改 UNION ALL 分開查再合併。IN/NOT IN:連續值用 BETWEEN,子查詢用 EXISTS。LIKE '%abc%' 前導模糊:全表掃描。改全文索引或 LIKE 'abc%'。FORCE INDEX(idx) 或應用層拼接 SQL。WHERE num/2=100 → WHERE num=200;WHERE SUBSTR(name,1,3)='abc' → WHERE name LIKE 'abc%'。WHERE YEAR(dt)=2023 → WHERE dt>='2023-01-01' AND dt<'2024-01-01'。INDEX(a,b,c) 必須用 a 才生效,順序要與索引一致。SELECT ... WHERE 1=0 建空表 → 用 CREATE TABLE ... LIKE。EXISTS 替代 IN:SELECT * FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id=a.id)。VARCHAR 代替 CHAR:變長省空間,小字段內存排序快。但定義長度不可慷慨 (見第 19 條)。SELECT *:顯式列出列,減少網絡、內存、IO、覆蓋索引機會增加。SELECT INTO 避免大量 Redo Log;小數據 CREATE TABLE + INSERT 緩解系統表壓力。TRUNCATE 後 DROP,避免長時間鎖定系統表。FAST_FORWARD 游標:唯讀、單向、只讀一次,性能優於 WHILE 循環。SET NOCOUNT ON:存儲過程/觸發器首尾加,減少 DONE_IN_PROC 網絡往返 (SQL Server 語法,MySQL 無此問題,但原理同:減少客戶端交互)。pt-archiver 分批歸檔、pt-online-schema-change 在線 DDL。long_query_time=1、log_queries_not_using_indexes=ON、pt-query-digest 定期分析。ANALYZE TABLE 定期更新 Cardinality,優化器才能做對選擇。Seconds_Behind_Master 告警、pt-heartbeat 高精度監控。Level 1 (ROI 最高) : SQL 改寫 + 索引設計 (解決 80% 問題)
Level 2 : 架構調整 (讀寫分離、分庫分表、緩存層)
Level 3 : 參數調優 (innodb_buffer_pool_size, tmp_table_size 等)
Level 4 : 硬件升級 (SSD、更大內存、更多 CPU)
Level 5 (最後手段) : 分佈式中間件、異構同步、重寫業務
金句:優化不是調參數,是改 SQL、設計索引、懂業務、控架構。 參數只能榨乾最後 10% 性能,前 90% 在代碼和設計裡。