mysql 數據庫是被普遍應用的關係型數據庫,其體積小、支持多處理器、開源並免費的特性使其在 Internet 中小型網站中的使用率尤爲高。在使用 mysql 的過程當中不規範的 SQL 編寫、非最優的策略選擇均可能致使系統性能甚至功能上的缺陷。
恰巧就在前幾天,本人所在公司的雲事業部舉辦了一場關於 mysql 的技術交流會,其中一個 part 正是聚焦於開發過程當中 mysql 數據庫設計及使用的常見問題,並提出相關優化方案。根據會議內容並查閱相關資料,本人對這個 part 進行了一次小結,結合本身的工做經歷及理解造成此文以供分享,但願能有助於各位同行解決工做中的相關問題。mysql
本文將就如下三個問題進行展開:程序員
1. 庫表設計sql
2. 慢 SQL 問題數據庫
3. 誤操做、程序 bug 時怎麼辦服務器
庫表設計併發
引擎選擇數據庫設計
在 mysql 5.1 中,引入了新的插件式存儲引擎體系結構,容許將存儲引擎加載到正在運新的 mysql 服務器中。使用 mysql 插件式存儲引擎體系結構,容許數據庫專業人員或者設計庫表的軟件開發人員爲特定的應用需求選擇專門的存儲引擎,徹底不須要管理任何特殊的應用編碼要求,也無需考慮全部的底層實施細節。所以,儘管不一樣的存儲引擎具備不一樣的能力,應用程序是與之分離的。此外,使用者能夠在服務器、數據庫和表格三個層級中存儲引擎,提供了極大的靈活性。函數
mysql 經常使用的存儲引擎包括 MYISAM、Innodb 和 Memory,其中各自的特色以下:工具
1. MYISAM : 全表鎖,擁有較高的執行速度,一個寫請求請阻塞另外相同表格的全部讀寫請求,併發性能差,佔用空間相對較小,mysql 5.5 及如下僅 MYISAM 支持全文索引,不支持事務。性能
2. Innodb:行級鎖(SQL 都走索引查詢),併發能力相對強,佔用空間是 MYISAM 的 2.5 倍,不支持全文索引(5.6 開始支持),支持事務。
3. Memory : 全表鎖,存儲在內存當中,速度快,但會佔用和數據量成正比的內存空間且數據在 mysql 重啓時會丟失。
基於以上特性,建議絕大部份都設置爲 innodb 引擎,特殊的業務再考慮選用 MYISAM 或 Memory ,如全文索引支持或極高的執行效率等。
分表方法
在數據庫表使用過程當中,爲了減少數據庫服務器的負擔、縮短查詢時間,經常會考慮作分表設計。分表分兩種,一種是縱向分表(將原本能夠在同一個表的內容,人爲劃分存儲在爲多個不一樣結構的表)和橫向分表(把大的表結構,橫向切割爲一樣結構的不一樣表)。
其中,縱向分表常見的方式有根據活躍度分表、根據重要性分表等。其主要解決問題以下:
1. 表與表之間資源爭用問題;
2. 鎖爭用機率小;
3. 實現核心與非核心的分級存儲,如UDB登錄庫拆分紅一級二級三級庫;
4. 解決了數據庫同步壓力問題。
橫向分表是指根據某些特定的規則來劃分大數據量表,如根據時間分表。其主要解決問題以下:
1. 單表過大形成的性能問題;
2. 單表過大形成的單服務器空間問題。
索引問題
索引是對數據庫表中一個或多個列的值進行排序的結構,創建索引有助於更快地獲取信息。 mysql 有四種不一樣的索引類型:
1. 主鍵索此 ( PRIMARY )
2. 惟一索引 ( UNIQUE )
3. 普通索引 ( INDEX )
4. 全文索引(FULLTEXT , MYISAM 及 mysql 5.6 以上的 Innodb )
創建索引的目的是加快對錶中記錄的查找或排序,索引也並不是越多越好,由於建立索引是要付出代價的:一是增長了數據庫的存儲空間,二是在插入和修改數據時要花費較多的時間維護索引。
在設計表或索引時,常出現如下幾個問題:
1. 少建索引或不建索引。這個問題最突出,建議建表時 DBA 能夠一塊兒協助把關。
2. 索引濫用。濫用索引將致使寫請求變慢,拖慢總體數據庫的響應速度(5.5 如下的 mysql 只能用到一個索引)。
3. 從不考慮聯合索引。實際上聯合索引的效率每每要比單列索引的效率更高。
4. 非最優列選擇。低選擇性的字段不適合建單列索引,如 status 類型的字段。
慢 SQL 問題
致使慢 SQL 的緣由
在遇到慢 SQL 狀況時,不能簡單的把緣由歸結爲 SQL 編寫問題(雖然這是最多見的因素),實際上致使慢 SQL 有不少因素,甚至包括硬件和 mysql 自己的 bug。根據出現的機率從大到小,羅列以下:
1. SQL編寫問題
2. 鎖
3. 業務實例相互幹繞對 IO/CPU 資源爭用
4. 服務器硬件
5. MYSQL BUG
由 SQL 編寫致使的慢 SQL 優化
針對SQL編寫致使的慢 SQL,優化起來仍是相對比較方便的。正如上一節提到的正確的使用索引能加快查詢速度,那麼咱們在編寫 SQL 時就須要注意與索引相關的規則:
1. 字段類型轉換致使不用索引,如字符串類型的不用引號,數字類型的用引號等,這有可能會用不到索引致使全表掃描;
2. mysql 不支持函數轉換,因此字段前面不能加函數,不然這將用不到索引;
3. 不要在字段前面加減運算;
4. 字符串比較長的能夠考慮索引一部份減小索引文件大小,提升寫入效率;
5. like % 在前面用不到索引;
6. 根據聯合索引的第二個及之後的字段單獨查詢用不到索引;
7. 不要使用 select *;
8. 排序請儘可能使用升序 ;
9. or 的查詢儘可能用 union 代替 (Innodb);
10. 複合索引高選擇性的字段排在前面;
11. order by / group by 字段包括在索引當中減小排序,效率會更高。
除了上述索引使用規則外,SQL 編寫時還須要特別注意一下幾點:
1. 儘可能規避大事務的 SQL,大事務的 SQL 會影響數據庫的併發性能及主從同步;
2. 分頁語句 limit 的問題;
3. 刪除表全部記錄請用 truncate,不要用 delete;
4. 不讓 mysql 幹多餘的事情,如計算;
5. 輸寫 SQL 帶字段,以防止後面表變動帶來的問題,性能也是比較優的 ( 涉及到數據字典解析,請自行查詢資料);
6. 在 Innodb上用 select count(*),由於 Innodb 會存儲統計信息;
7. 慎用 Oder by rand()。
分析診斷工具
在平常開發工做中,咱們能夠作一些工做達到預防慢 SQL 問題,好比在上線前預先用診斷工具對 SQL 進行分析。經常使用的工具備:
1. mysqldumpslow
2. mysql profile
3. mysql explain
具體使用及分析方法在此就不贅述,網上有豐富的資源能夠參考。
誤操做、程序 bug 時怎麼辦
提出這個問題顯然主要是針對剛開始工做的年輕同行們……實際上誤操做和程序 bug 致使數據誤刪或者混亂的問題並不是少見,可是剛入行的開發工做者會比較緊張。一個成熟的企業每每會有完善的數據管理規範和較豐富的數據恢復方案(初創公司除外),會進行數據備份和數據容災。當你發現誤操做或程序 bug 致使線上數據被誤刪或誤改動時,必定不能慌亂,應及時與 DBA 聯繫,第一時間進行數據恢復(嚴重時直接中止服務),儘量減小影響和損失。對於重要數據(如資金)的操做,在開發時必定要反覆進行測試,確保沒有問題後再上線。(Java高級程序員)學習交流QQ羣:478052716 你在學習Java的過程當中或者在工做中遇到什麼問題均可以來羣裏提問,阿里Java高級大牛直播講解知識點,分享知識,多年工做經驗的梳理和總結,帶着你們全面、科學地創建本身的技術體系和技術認知!能夠加羣找我要課堂連接 注意:是免費的 沒有開發經驗誤入哦! 非喜勿入!