三方法優(yōu)化MySQL數(shù)據(jù)庫查詢
在優(yōu)化查詢中,數(shù)據(jù)庫應用(如MySQL)即意味著對工具的操作與使用。使用索引、使用EXPLAIN分析查詢以及調(diào)整MySQL的內(nèi)部配置可達到優(yōu)化查詢的目的。
任何一位數(shù)據(jù)庫程序員都會有這樣的體會:高通信量的數(shù)據(jù)庫驅(qū)動程序中,一條糟糕的SQL查詢語句可對整個應用程序的運行產(chǎn)生嚴重的影響,其不僅消耗掉更多的數(shù)據(jù)庫時間,且它將對其他應用組件產(chǎn)生影響。
如同其它學科,優(yōu)化查詢性能很大程度上決定于開發(fā)者的直覺。幸運的是,像MySQL這樣的數(shù)據(jù)庫自帶有一些協(xié)助工具。本文簡要討論諸多工具之三種:使用索引,使用EXPLAIN分析查詢以及調(diào)整MySQL的內(nèi)部配置。
#1: 使用索引
MySQL允許對數(shù)據(jù)庫表進行索引,以此能迅速查找記錄,而無需一開始就掃描整個表,由此顯著地加快查詢速度。每個表最多可以做到16個索引,此外MySQL還支持多列索引及全文檢索。
給表添加一個索引非常簡單,只需調(diào)用一個CREATE INDEX命令并為索引指定它的域即可。列表A給出了一個例子:
列表 A
以下為引用的內(nèi)容: mysql> CREATE INDEX idx_username ON users(username); Query OK, 1 row affected (0.15 sec) Records: 1 Duplicates: 0 Warnings: 0 |
這里,對users表的username域做索引,以確保在WHERE或者HAVING子句中引用這一域的SELECT查詢語句運行速度比沒有添加索引時要快。通過SHOW INDEX命令可以查看索引已被創(chuàng)建(列表B)。
列表 B
以下為引用的內(nèi)容: mysql> SHOW INDEX FROM users; --------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | --------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ | users | 1 | idx_username | 1 | username | A | NULL | NULL | NULL | YES | BTREE | | --------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 1 row in set (0.00 sec) |
值得注意的是:索引就像一把雙刃劍。對表的每一域做索引通常沒有必要,且很可能導致運行速度減慢,因為向表中插入或修改數(shù)據(jù)時,MySQL不得不每次都為這些額外的工作重新建立索引。另一方面,避免對表的每一域做索引同樣不是一個非常好的主意,因為在提高插入記錄的速度時,導致查詢操作的速度減慢。這就需要找到一個平衡點,比如在設計索引系統(tǒng)時,考慮表的主要功能(數(shù)據(jù)修復及編輯)不失為一種明智的選擇。
#2: 優(yōu)化查詢性能
在分析查詢性能時,考慮EXPLAIN關(guān)鍵字同樣很管用。EXPLAIN關(guān)鍵字一般放在SELECT查詢語句的前面,用于描述MySQL如何執(zhí)行查詢操作、以及MySQL成功返回結(jié)果集需要執(zhí)行的行數(shù)。下面的一個簡單例子可以說明(列表C)這一過程:
列表 C
以下為引用的內(nèi)容: mysql> EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = 'IND'; +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ | 1 | SIMPLE | country | const | PRIMARY | PRIMARY | 3 | const | 1 | Using index | | 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4079 | Using where | +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ |
2 rows in set (0.00 sec)這里查詢是基于兩個表連接。EXPLAIN關(guān)鍵字描述了MySQL是如何處理連接這兩個表。必須清楚的是,當前設計要求MySQL處理的是country表中的一條記錄以及city表中的整個4019條記錄。這就意味著,還可使用其他的優(yōu)化技巧改進其查詢方法。例如,給city表添加如下索引(列表D):
列表 D
以下為引用的內(nèi)容: mysql> CREATE INDEX idx_ccode ON city(countrycode); Query OK, 4079 rows affected (0.15 sec) Records: 4079 Duplicates: 0 Warnings: 0 |
現(xiàn)在,當我們重新使用EXPLAIN關(guān)鍵字進行查詢時,我們可以看到一個顯著的改進(列表E):
列表 E
以下為引用的內(nèi)容: mysql> EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = 'IND'; +----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+ | 1 | SIMPLE | country | const | PRIMARY | PRIMARY | 3 | const | 1 | Using index | | 1 | SIMPLE | city | ref | idx_ccode | idx_ccode | 3 | const | 333 | Using where | +----+-------------+---------+-------+---------------+-----------+---------+-------+------+-------------+ 2 rows in set (0.01 sec) |
在這個例子中,MySQL現(xiàn)在只需要掃描city表中的333條記錄就可產(chǎn)生一個結(jié)果集,其掃描記錄數(shù)幾乎減少了90%!自然,數(shù)據(jù)庫資源的查詢速度更快,效率更高。
關(guān)鍵字:MySQL、數(shù)據(jù)庫
新文章:
- CentOS7下圖形配置網(wǎng)絡的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機IP講解
- CentOS7使用hostapd實現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認iptable規(guī)則詳解