## 8.1 優化概述
數據庫性能取決于數據庫級別的多個因素, 例如表, 查詢和配置設置. 這些軟件構造導致了硬件級別的 CPU 和 I/O 操作, 你必須盡可能最小化并盡可能提高效率. As you work on database performance, you start by learning the high-level rules and guidelines for the software side, and measuring performance using wall-clock time. 隨著你成為專家, 你將會學習更多內部發生的事情, 并開始測試 CPU 周期 和 I/O 操作等內容.
典型的用戶目標是從現有的軟件和硬件配置中獲得最佳的數據庫性能. 高級用戶尋找機會來改進 MySQL 軟件本身, 或者開發自己的存儲引擎和硬件設備來擴展 MySQL 生態系統.
- [數據庫級別優化](#數據庫級別優化)
- [硬件級別優化](#硬件級別優化)
- [平衡可移植性和性能](#平衡可移植性和性能)
### 數據庫級別優化
使數據庫應用快速運行的最重要因素是它的基本設計:
- 表的結構是否正確? In particular, do the columns have the right data types, and does each table have the appropriate columns for the type of work? 例如, 執行頻繁更新的應用程序常常很多表只有很少的列, 而分析大量數據的應用程序通常只有很少的表有很多的列.
- 是否有適當的[索引]((https://dev.mysql.com/doc/refman/8.0/en/optimization-indexes.html))來提升查詢效率?
- 你是否為每個表使用合適的存儲引擎, 并利用了每個存儲引擎的優點和特性? 特別是, 諸如 [`InnoDB`](https://dev.mysql.com/doc/refman/8.0/en/optimizing-innodb.html) 之類的事務存儲引擎或諸如 [`MyISAM`](https://dev.mysql.com/doc/refman/8.0/en/optimizing-myisam.html) 之類的非事務性存儲引擎的選擇對于性能和可伸縮性非常重要.
> **注意**
>
> InnoDB 是新表的默認存儲引擎. 實際上, 先進的 `InnoDB` 性能特征意味著 `InnoDB` 表通常優于更簡單的 `MyISAM` 表, 尤其是對與繁忙的數據.
- 每個表是否使用了適當的行格式? 這個選擇也取決于使用的表的存儲引擎. 特別是, 壓縮表是否較少的磁盤空間, 因此需要較少的磁盤 I/O 來讀取和寫入數據. 壓縮適用于所有使用 `InnoDB` 表的工作負載, 也適用于只讀 `MyISAM` 表.
- 應用程序是否使用了適當的[鎖策略](https://dev.mysql.com/doc/refman/8.0/en/locking-issues.html)? 例如, 在可能的情況下允許共享訪問, 以便數據庫操作可以并發運行, 在適當的情況下請求獨占訪問, 以便關鍵操作獲得優先級. 同樣, 搜索引擎的選擇也很重要. `InnoDB` 存儲引擎可以在不需要你參與的情況下處理大多數鎖問題, 從而提高數據庫的并發性, 減少代碼的實驗和調優.
- Are all[ memory areas used for caching](https://dev.mysql.com/doc/refman/8.0/en/buffering-caching.html) sized correctly? 也就是說, 足夠大以容納頻繁訪問的數據, 但也不能太大以至于超載物理內存并導致分頁. 要配置的最主要內存區域是 `InnoDB` 緩沖池(buffer pool) 和 `MyISAM` 鍵緩存(key cache).
### 硬件級別優化
隨著數據庫變得越來越繁忙, 任何數據庫應用程序最終都會達到硬件限制. DBA 必須評估是否可以調優應用程序或重新配置服務器以避免這些[瓶頸](https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_bottleneck), 或者是需要更多的硬件資源. 系統瓶頸通常來自于下面這些:
- 磁盤尋道. 磁盤需要一段時間才能找到一塊數據. 對于現代磁盤, 這一過程的平均時間通常低于10ms, 所以理論上我們可以每秒進行100次搜索. 這段時間隨著新磁盤的使用而緩慢改善并且很難對單表進行優化. 優化尋道時間的方法是將數據分布到多個磁盤上.
- 磁盤讀寫. 當磁盤位于正確的位置時, 我們需要讀取或寫入數據. 使用現代磁盤, 一個磁盤可提供至少 10-20MB/s 的吞吐量. 這比尋道更容易優化, 因為你可以從多個磁盤并行讀取.
- CPU 周期. 當數據在主存儲器時, 我們必須處理他們以獲得我們的結果. 與內存量相比, 具有較大的表時最常見的限制因素. 但是小表, 速度通常不是問題.
- 內存帶寬. 當 CPU 需要的數據超過 CPU 緩存容量時, 主內存帶寬將成為瓶頸. 對大多數系統來說, 這是一個不常見的瓶頸, 但是需要注意.
### 平衡可移植性和性能
To use performance-oriented SQL extensions in a portable MySQL program, you can wrap MySQL-specific keywords in a statement within `/*! */` comment delimiters. 其它 SQL 服務器忽略注釋關鍵字. 有關撰寫注釋的信息, 參閱 [Section 9.6, “注釋語法”](https://dev.mysql.com/doc/refman/8.0/en/comments.html).
- 簡介
- 前言和法律條款
- 安裝和更新 MySQL
- 在 Linux 上安裝 MySQL
- 在 Linux 上使用 APT 庫安裝 MySQL
- 在 Linux 上使用 Docker 部署 MySQL
- 使用 Docker 部署 MySQL 服務器的基本步驟
- 使用 Docker 部署 MySQL 服務器的更多主題
- 教程
- 連接到服務器和從服務器斷開
- 輸入查詢
- 創建和使用數據庫
- 創建和選擇數據庫
- 創建表
- 將數據加載到表中
- 從表中檢索數據
- 選擇所有數據
- 選擇特定行
- 選擇指定列
- 行排序
- 日期計算
- 處理 NULL 值
- 模式匹配
- 計算行數
- 使用多個表
- 獲取數據庫和表的信息
- 在批處理模式使用 mysql
- 常見查詢示例
- 列的最大值
- 包含某一行最大值的記錄
- 每組中列的最大值
- 擁有某個字段的組間最大值的行
- 使用用戶自定義變量
- 使用外鍵
- 兩個鍵上搜索
- 計算每日訪問量
- 使用 AUTO_INCREMENT
- 在 Apache 中使用 MySQL
- MySQL 程序
- MySQL 客戶端程序
- mysql — MySQL 命令行客戶端
- 優化
- 優化概述
- 優化 SQL 語句
- 優化和索引
- 優化數據庫結構
- 優化 InnoDB 表
- 優化 MyISAM 表
- 優化 MEMORY 表
- 理解查詢執行計劃
- 控制查詢優化器
- 緩沖和緩存
- 優化鎖操作
- 優化 MySQL 服務器
- 測量性能 (Benchmarking)
- 檢查線程信息