溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何優(yōu)化MySQL?

發(fā)布時(shí)間:2020-05-15 16:19:56 來源:億速云 閱讀:245 作者:Leah 欄目:MySQL數(shù)據(jù)庫(kù)

如何優(yōu)化MySQL?針對(duì)這個(gè)問題,今天小編總結(jié)這篇有關(guān)MySQL優(yōu)化的文章,希望幫助更多想學(xué)習(xí)MySQL優(yōu)化的同學(xué)找到更加簡(jiǎn)單易行的辦法。

1. 選取最適用的字段屬性

表中字段的寬度設(shè)得盡可能?。篶har 的上限為 255 字節(jié)(固定占用空間),varchar 的上限 65535 字節(jié)(實(shí)際占用空間),text 的上限為 65535。char 比 varchar 處理效率高。

盡量把字段設(shè)置為 NOT NULL,執(zhí)行查詢的時(shí)候,數(shù)據(jù)庫(kù)不用去比較 NULL 值。

2. 使用連接(JOIN)來代替子查詢 (Sub-Queries)

連接(JOIN)之所以更有效率一些,是因?yàn)?MySQL 不需要在內(nèi)存中創(chuàng)建臨時(shí)表來完成這個(gè)邏輯上的需要兩個(gè)步驟的查詢工作(聯(lián)合查詢的條件加索引更快)。

3. 使用聯(lián)合 (UNION) 來代替手動(dòng)創(chuàng)建的臨時(shí)表

把需要使用臨時(shí)表的兩條或更多的 SELECT 查詢合并的一個(gè)查詢中。

SELECT Name, Phone FROM client UNION SELECT Name, BirthDate FROM author  UNION SELECT Name, Supplier FROM product;

4. 事務(wù)

盡管我們可以使用子查詢(Sub-Queries)、連接(JOIN)和聯(lián)合(UNION)來創(chuàng)建各種各樣的查詢,但不是所有的數(shù)據(jù)庫(kù)操作都可以只用一條或少數(shù)幾條 SQL 語(yǔ)句就可以完成的。更多的時(shí)候是需要用到一系列的語(yǔ)句來完成某種工作。

作用是:要么語(yǔ)句塊中每條語(yǔ)句都操作成功,要么都失敗。換句話說,就是可以保持?jǐn)?shù)據(jù)庫(kù)中數(shù)據(jù)的一致性和完整性。事物以 BEGIN 關(guān)鍵字開始,COMMIT 關(guān)鍵字結(jié)束。在這之間的一條 SQL 操作失敗,那么,ROLLBACK 命令就可以把數(shù)據(jù)庫(kù)恢復(fù)到 BEGIN 開始之前的狀態(tài)。

5. 鎖定表

盡管事務(wù)是維護(hù)數(shù)據(jù)庫(kù)完整性的一個(gè)非常好的方法,但卻因?yàn)樗莫?dú)占性,有時(shí)會(huì)影響數(shù)據(jù)庫(kù)的性能,尤其是在很大的應(yīng)用系統(tǒng)中。由于在事務(wù)執(zhí)行的過程中,數(shù)據(jù)庫(kù)將會(huì)被鎖定,因此其它的用戶請(qǐng)求只能暫時(shí)等待直到該事務(wù)結(jié)束。

LOCK TABLE inventory WRITE 
SELECT Quantity FROM inventory 
WHEREItem='book'; 
... 
UPDATE inventory SET Quantity=11 
WHEREItem='book'; 
UNLOCK TABLES

這里,我們用一個(gè) SELECT 語(yǔ)句取出初始數(shù)據(jù),通過一些計(jì)算,用 UPDATE 語(yǔ)句將新值更新到表中。包含有 WRITE 關(guān)鍵字的 LOCK TABLE 語(yǔ)句可以保證在 UNLOCK TABLES 命令被執(zhí)行之前,不會(huì)有其它的訪問來對(duì) inventory 進(jìn)行插入、更新或者刪除的操作。

6、使用外鍵

鎖定表的方法可以維護(hù)數(shù)據(jù)的完整性,但是它卻不能保證數(shù)據(jù)的關(guān)聯(lián)性。這個(gè)時(shí)候我們就可以使用外鍵。例如,外鍵可以保證每一條銷售記錄都指向某一個(gè)存在的客戶。在這里,外鍵可以把 customerinfo 表中的 CustomerID 映射到 salesinfo 表中 CustomerID,任何一條沒有合法 CustomerID 的記錄都不會(huì)被更新或插入到 salesinfo 中。

CREATE TABLE customerinfo 
( 
CustomerID INT NOT NULL , 
PRIMARY KEY ( CustomerID ) 
) TYPE = INNODB; 
CREATE TABLE salesinfo 
( 
SalesID INT NOT NULL, 
CustomerID INT NOT NULL, 
PRIMARY KEY(CustomerID, SalesID), 
FOREIGN KEY (CustomerID) REFERENCES customerinfo 
(CustomerID) ON DELETECASCADE 
) TYPE = INNODB;

注意例子中的參數(shù) “ON DELETE CASCADE”。該參數(shù)保證當(dāng) customerinfo 表中的一條客戶記錄被刪除的時(shí)候,salesinfo 表中所有與該客戶相關(guān)的記錄也會(huì)被自動(dòng)刪除。如果要在 MySQL 中使用外鍵,一定要記住在創(chuàng)建表的時(shí)候?qū)⒈淼念愋投x為事務(wù)安全表 InnoDB 類型。該類型不是 MySQL 表的默認(rèn)類型。定義的方法是在 CREATE TABLE 語(yǔ)句中加上 TYPE=INNODB。

7. 使用索引

查詢語(yǔ)句當(dāng)中包含有 MAX (), MIN () 和 ORDERBY 這些命令的時(shí)候,性能提高更為明顯。

索引應(yīng)建立在那些將用于 JOIN, WHERE 判斷和 ORDER BY 排序的字段上。盡量不要對(duì)數(shù)據(jù)庫(kù)中某個(gè)含有大量重復(fù)的值的字段建立索引。對(duì)于一個(gè) ENUM 類型的字段來說,出現(xiàn)大量重復(fù)值是很有可能的情況,例如 customerinfo 中的 “province”.. 字段,在這樣的字段上建立索引將不會(huì)有什么幫助;相反,還有可能降低數(shù)據(jù)庫(kù)的性能。

普通索引(由關(guān)鍵字 KEY 或 INDEX 定義的索引)的唯一任務(wù)是加快對(duì)數(shù)據(jù)的訪問速度。因此,應(yīng)該只為那些最經(jīng)常出現(xiàn)在查詢條件(WHEREcolumn=)或排序條件(ORDERBYcolumn)中的數(shù)據(jù)列創(chuàng)建索引。

唯一索引的好處:一是簡(jiǎn)化了 MySQL 對(duì)這個(gè)索引的管理工作,這個(gè)索引也因此而變得更有效率;二是 MySQL 會(huì)在有新記錄插入數(shù)據(jù)表時(shí),自動(dòng)檢查新記錄的這個(gè)字段的值是否已經(jīng)在某個(gè)記錄的這個(gè)字段里出現(xiàn)過了;如果是,MySQL 將拒絕插入那條新記錄。也就是說,唯一索引可以保證數(shù)據(jù)記錄的唯一性。在許多場(chǎng)合,創(chuàng)建唯一索引的目的往往不是為了提高訪問速度,而只是為了避免數(shù)據(jù)出現(xiàn)重復(fù)。

8. 優(yōu)化的查詢語(yǔ)句

SELECT FROM order WHERE YEAR(OrderDate)<2001; 
SELECT FROM order WHERE OrderDate<"2001-01-01";
SELECT FROM inventory WHERE Amount/7<24; 
SELECT FROM inventory WHERE Amount<24*7;

避免在查詢中讓 MySQL 進(jìn)行自動(dòng)類型轉(zhuǎn)換,因?yàn)檗D(zhuǎn)換過程也會(huì)使索引變得不起作用。

9. 索引失效情況

like 以 % 開頭,索引無效;當(dāng) like 前綴沒有 %,后綴有 % 時(shí),索引有效。

or 語(yǔ)句前后沒有同時(shí)使用索引。當(dāng) or 左右查詢字段只有一個(gè)是索引,該索引失效,只有當(dāng) or 左右查詢字段均為索引時(shí),才會(huì)生效。

組合索引,不是使用第一列索引,索引失效。

數(shù)據(jù)類型出現(xiàn)隱式轉(zhuǎn)化。如 varchar 不加單引號(hào)的話可能會(huì)自動(dòng)轉(zhuǎn)換為 int 型,使索引無效,產(chǎn)生全表掃描。

在索引字段上使用 not,<>,!=。不等于操作符是永遠(yuǎn)不會(huì)用到索引的,因此對(duì)它的處理只會(huì)產(chǎn)生全表掃描。 優(yōu)化方法: key<>0 改為 key>0 or key<0。

當(dāng)全表掃描速度比索引速度快時(shí),mysql 會(huì)使用全表掃描,此時(shí)索引失效。

應(yīng)盡量避免在 where 子句中使用 or,and,in,not in 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,合理使用 union all(允許重復(fù)的值,請(qǐng)使用 UNION ALL)。

select id from t where num=10 or num=20

可以這樣查詢:

select id from t where num=10    
union all    
select id from t where num=20

10. 引擎的選取

MyISAM 索引文件在數(shù)據(jù)庫(kù)中存放的對(duì)應(yīng)表的磁盤文件有.frm,.MYD,*.MYI 結(jié)尾的三個(gè)文件:

frm 文件是存放的表結(jié)構(gòu),表的定義信息;

MYD 文件是存放著表中的數(shù)據(jù);

MYI 文件存放著表的索引信息;

InnoDB 存儲(chǔ)引擎在磁盤中存放的對(duì)應(yīng)的表的磁盤文件有.frm,.ibd 這兩個(gè)文件;

frm 文件是存放表結(jié)構(gòu),表的定義信息;

ibd 文件是存放 表中的數(shù)據(jù)、索引信息;

詳細(xì)出處參考:https://blog.csdn.net/jinxingfeng_cn/article/details/16878355

性能方面的優(yōu)化:

explain 執(zhí)行計(jì)劃 ==>https://blog.csdn.net/yhl_jxy/article/details/88570154

一、分表的分類(單表記錄條數(shù)達(dá)到百萬到千萬級(jí)別時(shí)就要使用分表)

1. 縱向分表

文章標(biāo)題,作者,分類,創(chuàng)建時(shí)間等,是變化頻率慢,查詢次數(shù)多,而且最好有很好的實(shí)時(shí)性的數(shù)據(jù),我們把它叫做冷數(shù)據(jù)。

瀏覽量,回復(fù)數(shù)等,類似的統(tǒng)計(jì)信息,或者別的變化頻率比較高的數(shù)據(jù),我們把它叫做活躍數(shù)據(jù)。

首先存儲(chǔ)引擎的使用不同,冷數(shù)據(jù)使用 MyIsam 可以有更好的查詢數(shù)據(jù)?;钴S數(shù)據(jù),可以使用 Innodb , 可以有更好的更新速度。

就是把原來一張表里的字段,冷數(shù)據(jù)的字段和活躍數(shù)據(jù)的字段分別建立 2 張表來管理。

2. 橫向分表

把大的表結(jié)構(gòu),橫向切割為同樣結(jié)構(gòu)的不同表,如,用戶信息表,user_1,user_2 等,表結(jié)構(gòu)是完全一樣。

二、慢查詢

show variables like 'slow%';
show global status like 'slow%';

使用 mysqlreport;

正確使用索引:explain 分析查詢語(yǔ)句,組合索引,索引副作用(占空間、update)

開啟慢查詢?nèi)罩?、使用慢查詢分析工?mysqlsla;

索引緩存、索引代價(jià)(插入更新索引);

表鎖,行鎖,行鎖副作用(update 多時(shí)候變慢),在 select 和 update 混合的情況下,行鎖巧妙解決了讀寫互斥的問題;

開啟使用查詢緩存;

修改臨時(shí)表內(nèi)存空間;

開啟線程池;

MySQL Query 語(yǔ)句優(yōu)化的基本思路和原則

1、優(yōu)化需要優(yōu)化的 Query;

2、定位優(yōu)化對(duì)象的性能瓶頸;

3、明確優(yōu)化目標(biāo);

4、從 Explaing 入手;

5、多使用 Profile;

6、永遠(yuǎn)用小結(jié)果集推動(dòng)大的結(jié)果集;

7、盡可能在索引中完成排序;

8、只取自己需要的 Columns;

9、僅僅使用最有效的過濾條件;

10、盡可能避免復(fù)雜的 Join 和子查詢。

關(guān)于MySQL優(yōu)化就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果喜歡這篇文章,不如把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI