1. 程式人生 > 其它 >MySQL優化方案(一)優化SQL指令碼與索引

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”);

哪些情況下應該使用索引?
  • 當表中的欄位唯一約束。
  • 表中主鍵自動建立唯一索印。
  • 有需要之間面向查詢條件的欄位,比如,公司的註冊編號。
  • 表中含有外來鍵的,建立的與其他表的一定關係。
  • 排序的欄位。當通過某欄位進行排序查詢的時候,通過索引訪問提高速度。
哪些情況下不適合使用索引?
  • 表記錄太少。
  • 經常要進行增、刪、修改的表。
  • 經常與主欄位一起捆綁查詢,但是主欄位索引值比較多的欄位。