MySQL優化方案(一)優化SQL指令碼與索引
MySQL的優化方案有哪一些?
本文記錄MySQL優化方案 ,梗概如下:
- 優化SQL
- 優化索引
(一)優化SQL
1、通過MySQL自有的優化語句
優化SQL語句,通過指令碼命令來了解執行率較低的語句,顯示一下狀態等。
- SHOW命令
SHOW Status可以瞭解SQL的執行頻率。可以顯示日誌,顯示特定的資料庫、表、索引以及程序還有許可權表中的資訊等等。
介紹一些常見的欄位
Innodb_rows_read:Select查詢返回的行數。
Innodb_rows_inserted:執行INSERT操作插入的行數。
Innodb_rows_updated:執行UPDATE操作更新的行數。
Innodb_rows_deleted:執行DELETE操作刪除的行數。
- EXPLAIN
通過EXPALIN命令可以分析低效的SQL執行計劃。通過這個命令,可以知道MySQL是如何執行Select語句的資訊,資訊也包括了Select在執行的時候,各個表之間的聯絡以及是什麼樣的聯絡,使用了哪一種index。
比如我們想統計某個公司的電子銀行賬戶([email protected])為交物業費所支付的總金額。 需要管理客戶表(Customer)、付款表(Payment),並要對付款金額(Amount)欄位求和(Sum)。
# explain select sum(amount) from customer a.payment b where 1=1 and a.customer_id = b.customer_id and email = "[email protected]"
MySQL 在表中找到所需要的行的方式,也叫做訪問型別,有一下幾種:
ALL, index, range, ref, eq_ref, const/system, NULL.
從左往右,效能變化是:差—>好.
- OPTIMIZE
Optimize 語句目前支援MyIASM和BDB表。允許使用者恢復空間和合並資料檔案碎片。介紹一下我的優化MySQL表和碎片整理以恢復空間的思路。
① 首先確認MySQL資料庫中是否存在碎片
我隨機找了一個數據庫。
我隨機找了一個數據庫。
查詢出來表中沒有資料,沒有碎片,不是薯片。要是有呢?
②使用優化命令(第一鍾方式)
- Optimize table TableName;
- Optimize table TableName1,TableName2…;
執行完畢,Msg_text顯示
‘numysql.SYS_APP_USER’, ‘optimize’, ‘note’, ‘Table does not support optimize, doing recreate + analyze instead’
原因是我伺服器上的的MySQL是InnoDB儲存引擎。
Stack Overflow 也有解釋:
這裡說明一下,Optimize命令可以在MyISAM、InnoDB儲存引擎中使用進行優化表的操作。但是兩種不同的儲存引擎,它的優化方式是不一樣的。在MyISAM中,是先分析這張表,然後會整理相關的MySQL datafile,之後回收未使用的空間;在InnoDB中,回收空間是簡單通過Alter table進行整理空間。
在優化期間,MySQL會建立一個臨時表,優化完成之後會刪除原始表,然後會將臨時表rename成為原始表。
③使用mysqlcheck命令(第二種方式)
# mysqlcheck -o DatabaseName TableName -u root -pPassCode
DatabaseName.TableName OK
mysqlcheck 是Linux中的rompt,-o是代表Optimize。
④優化所有的表
mysqlcheck -o DatabaseName -u root -pPassCode
mysqlcheck -o --all-databases -u root -pPassCode
優化完成之後,在用開始的語句檢查
select table_name,
round(data_length/1024/1024) as data_length_mb,
round(data_free/1024/1024) as data_free_mb
from information_schema.tables
where round(data_free/1024/1024) > 500
order by data_free_mb;
2、通過規範MySQL 指令碼語句書寫
①避免SELECT *
MySQL 在解析的過程中,會通過查詢資料字典將”*”按序轉換成所有列名,這會大大的耗費資源和時間。在書寫MySQL語句的時候,我們應該需要查詢那一列就寫那一列。
②GROUP BY 優化
提高GROUP BY的效率,精簡語句,將不需的記錄在GROUP之前去掉。這樣好好學語文分析一下要求的句子句子結構了。
③ORDER BY優化
任何的在ORDER BY語句的非索引項或者是有計算表達都將降低查詢速度。
可以rewrite ORDER BY語句使用索引。
絕對避免在ORDER BY中使用表示式。
為所使用的列建立另外一個索引。
④EXISTS 代替IN
⑤varchar/nvarchar 代替 char/nchar
欄位儲存空間小,可以節省儲存空間。
⑥能用DISTINCT就不用GROUP BY
⑦使用!= 或者 < >
儘量避免這樣。MySQL會想Select * 那樣進行全表掃描遍歷。使用> <給定區間較好。
(二)優化索引
MySQL的索引是在儲存引擎層面實現的,並不是在伺服器層面實現的。所以每一種的儲存引擎的索引都是不是完全相同的。
MySQL目前提供了一下4種索引(概念)。
- B-Tree索引:最常見的搜尋引擎。大部分的搜尋搜尋引擎是支援B-Tree。
- Hash索引:這個搜尋引擎只有Memory引擎支援。
- R-Tree索引:又稱為空間索引。空間索引要是MyISAM的一個特殊搜尋引擎。
- Full-text:全文索引。全文索引也是MyISAM的一個特殊的索引型別。InnoDB 從MySQL 5.6版本開始提供了對全文的支援。
三種引擎對四種索引的支援情況
索引(語法)的分類(大小寫混淆僅為可讀性好一些,不建議這樣做)
- 普通索引
ALTER TABLE tableName ADD INDEX index_name(“column”);
- 主鍵索引
ALTER TABLE tableName ADD PRIMARY KEY index_name(“column”);
- 唯一索引
ALTER TABLE tableName ADD UNIQUE index_name(“column”);
- 全文索引
ALTER TABLE tableName ADD FULLTEXT index_name(“column”);
- 多列索引
ALTER TABLE tableName ADD INDEX index_name(“column1″,”column2”);
哪些情況下應該使用索引?
- 當表中的欄位唯一約束。
- 表中主鍵自動建立唯一索印。
- 有需要之間面向查詢條件的欄位,比如,公司的註冊編號。
- 表中含有外來鍵的,建立的與其他表的一定關係。
- 排序的欄位。當通過某欄位進行排序查詢的時候,通過索引訪問提高速度。
哪些情況下不適合使用索引?
- 表記錄太少。
- 經常要進行增、刪、修改的表。
- 經常與主欄位一起捆綁查詢,但是主欄位索引值比較多的欄位。