在互聯網大廠必須遵照的MySql開發軍規

核心mysql

  • 不在數據庫作運算
  • 單表數據量:一年內單表純INT不超過1000W,含CHAR不超500W。單庫不超過300~400表
  • 表字段儘可能少,上限控制在20~50個
  • 適當能夠冗餘(平衡範式和冗餘)
  • 拒絕大sql,大事務,大批量

字段sql

  1. 數值類型的字節和運用範圍
  2. 若是能夠,將字符串轉化爲數字存儲。能夠加快查詢速度和節省空間,舉例用INT代替CHAR(15)來存儲IP
  3. 優先使用SET和ENUM...(可能有問題!)
  4. 避免使用NULL
  5. 少用TEXT/BLOB,若是必須使用(超過varchar最大限制64k)則必須拆分到單獨的表
  6. 不在數據庫存圖片

索引數據庫

  1. 能不加的索引儘可能不加,最好不超過字段數的20%(如:性別不加),結合核心SQL優先考慮覆蓋索引
  2. 字符字段必須建前綴索引。因爲字符串很長,一般能夠索引開始的幾個字符,而不是所有值,以節約空間並獲得好的性能。
  3. 不在索引列進行數學運算和函數運算(會致使沒法使用索引 => 全表掃描),如where id+1 = 100 和 id = 100 - 1,效率差很遠
  4. 自增列或全局ID作INNODB的主鍵
  5. 儘可能不用外鍵(由程序保證約束),高併發的時候容易死鎖

SQL緩存

  1. SQL語句儘量簡單,由於一條SQL只能在一個CPU運算,在高併發的狀況下,可能一條大SQL就把整個數據庫堵死。而簡單的SQL緩存命中率更高,減小鎖表的時間(特別是MyISAM),用上多CPU
  2. 保持事務、DB鏈接足夠短,即開即用、用完就關。與事務無關操做放到事務外面,減小鎖資源的佔用;在不破壞一致性前提下,使用多個短事務代替長事務(如:發帖時的圖片上傳等待)
  3. 儘量少用存儲過程,少用觸發器,減用MySQL函數對結果進行處理(交由客戶端程序負責)
  4. 儘可能少用select *,只取須要數據列,爲使用覆蓋索引提供可能性,減小臨時表生成,更安全
  5. 用in()代替or,由於or的效率是O(n),而in()的效率是O(Log n)。如:where a = 1 OR a = 100 與 where a IN (1, 100)
  6. merge index每每很弱智,因此用union代替對多字段的or查詢。如:select * from t where a = 1 OR b = 2 與 select * from t where a = 1 UNION select * from t where b = 2
  7. 儘可能避免負向查找,如NOT、!=等
  8. 儘可能避免%前綴模糊查詢,因爲使用的是B+ Tree,前綴模糊使用不了索引,致使全表掃描(後綴模糊速度相對快不少)
  9. 減小COUNT(*),使用COUNT(col),前者資源開銷大,儘可能少用。MyISAM不帶WHERE COUNT()而INNODB帶WHERE COUNT()。 計數的統計能夠採用的方法:實時統計可使用memcache,雙向更新,凌晨跑基準;非實時統計儘可能用單獨統計表,按期重算
  10. LIMIT高效分頁:傳統的方法是select * from t limit 10000, 10,推薦的方法是select * from t where id > 23423 limit 10。LIMIT的偏移量越大則越慢。還有一些高效的方法有:先取id來LIMIT偏移,減小總體的數據偏移;取到須要的id,與原表JOIN;程序取ID,而後用IN來填寫。select * from t where id >= (select id from t limit 10000, 1) limit 10 , select * from t INNER JOIN (select id from t limit 10000, 10) USING (id) , select id from t limit 10000, 10; select * from t where id in (123, 456...)
  11. 若無需對結果進行去重,則用UNION ALL而非UNION(UNION有去重開銷)
  12. 分解JOIN聯接來保證高併發。高併發DB不建議進行兩個表以上的JOIN
  13. group by會默認自動升序排序,若是須要去掉排序,須要指定order by NULL
  14. 比較原則:數字對數字、字符對字符。若是數值列與字符類型做比較,同時轉換成雙精度;若是字符列與數值類型做比較,字符列整列轉數值,且不會使用索引查詢
  15. load data導入數據比insert快約20倍(不須要刷新緩存)
  16. 儘可能不使用insert...select(延遲、同步出錯)
  17. 大批量更新凌晨操做,避開高峯
  18. SQL的一些命令:explain, show profile, mysqlsla, mysqldumpslow, show slow log, show processlist, show QUERY_RESPONSE_TIME(Percona)

約定安全

  1. 數據庫在不一樣時期使用不一樣的:實時數據用real庫,模擬環境用sim庫,測試用qa庫,開發用dev庫
  2. 禁止未經DBA確認的子查詢(大部分狀況優化較差,特別是WHERE中使用IN id的子查詢,通常能夠用JOIN改寫)
  3. 不要在程序上加鎖數據庫,由於外部鎖對數據庫不可控,高併發時是災難,而且極難調試排查(能夠採用事務來解決)
  4. 統一字符集:UTF-8,校對規則:utf8_general_ci
  5. 庫和表的名稱統一用小寫(大小寫敏感、且不一樣操做系統都有不一樣的限制);字段名大小寫不敏感;索引名默認爲idx_字段名;庫名用縮寫,儘可能在2~7個字母;避免用保留字命名
相關文章
相關標籤/搜索