MySQL基础总结(三)
MySQL基礎(chǔ)總結(jié)(三)
文章目錄
- MySQL基礎(chǔ)總結(jié)(三)
- 七、鎖機(jī)制
- 1.鎖的分類
- 從對數(shù)據(jù)操作的類型分類:
- 從對數(shù)據(jù)操作的粒度分類:
- 2.MyISAM 表鎖
- 3.InnoDB 行鎖
- 4.加鎖機(jī)制
- 5.鎖模式(InnoDB有三種行鎖的算法)
- 6.select for update有什么含義,會鎖表還是鎖行還是其他
- 7.死鎖
- 死鎖產(chǎn)生:
- 檢測死鎖:
- 死鎖恢復(fù):
- 外部鎖的死鎖檢測:
- 死鎖影響性能:
- MyISAM避免死鎖:
- InnoDB避免死鎖:
- 改變事務(wù)隔離級別
- 八、性能優(yōu)化
- 1.影響mysql的性能因素
- 2.性能分析
- MySQL Query Optimizer
- MySQL常見瓶頸
- 性能下降SQL慢 執(zhí)行時間長 等待時間長 原因分析
- MySQL常見性能分析手段
- 3.性能優(yōu)化
- 索引優(yōu)化
- 一般性建議
- 查詢優(yōu)化
- order by關(guān)鍵字優(yōu)化
- GROUP BY關(guān)鍵字優(yōu)化
- 數(shù)據(jù)類型優(yōu)化
七、鎖機(jī)制
鎖是計算機(jī)協(xié)調(diào)多個進(jìn)程或線程并發(fā)訪問某一資源的機(jī)制。
在數(shù)據(jù)庫中,除傳統(tǒng)的計算資源(如CPU、RAM、I/O等)的爭用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。
數(shù)據(jù)庫鎖定機(jī)制簡單來說,就是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性,而使各種共享資源在被并發(fā)訪問變得有序所設(shè)計的一種規(guī)則。
- 打個比方,我們到淘寶上買一件商品,商品只有一件庫存,這個時候如果還有另一個人買,那么如何解決是你買到還是另一個人買到的問題?
- 這里肯定要用到事物,我們先從庫存表中取出物品數(shù)量,然后插入訂單,付款后插入付款表信息,然后更新商品數(shù)量。
- 在這個過程中,使用鎖可以對有限的資源進(jìn)行保護(hù),解決隔離和并發(fā)的矛盾。
1.鎖的分類
從對數(shù)據(jù)操作的類型分類:
- 讀鎖(共享鎖):針對同一份數(shù)據(jù),多個讀操作可以同時進(jìn)行,不會互相影響
- 寫鎖(排他鎖):當(dāng)前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖
從對數(shù)據(jù)操作的粒度分類:
為了盡可能提高數(shù)據(jù)庫的并發(fā)度,每次鎖定的數(shù)據(jù)范圍越小越好,理論上每次只鎖定當(dāng)前操作的數(shù)據(jù)的方案會得到最大的并發(fā)度,但是管理鎖是很耗資源的事情(涉及獲取,檢查,釋放鎖等動作),因此數(shù)據(jù)庫系統(tǒng)需要在高并發(fā)響應(yīng)和系統(tǒng)性能兩方面進(jìn)行平衡,這樣就產(chǎn)生了“鎖粒度(Lock granularity)”的概念。
- 表級鎖:開銷小,加鎖快;不會出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低(MyISAM 和 MEMORY 存儲引擎采用的是表級鎖);
- 行級鎖:開銷大,加鎖慢;會出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高(InnoDB 存儲引擎既支持行級鎖也支持表級鎖,但默認(rèn)情況下是采用行級鎖);
- 頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間;會出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。
適用:從鎖的角度來說,表級鎖更適合于以查詢?yōu)橹?#xff0c;只有少量按索引條件更新數(shù)據(jù)的應(yīng)用,如Web應(yīng)用;而行級鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時又有并發(fā)查詢的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。
2.MyISAM 表鎖
- MyISAM 的表鎖有兩種模式:
- 表共享讀鎖 (Table Read Lock):不會阻塞其他用戶對同一表的讀請求,但會阻塞對同一表的寫請求;
- 表獨占寫鎖 (Table Write Lock):會阻塞其他用戶對同一表的讀和寫操作;
MyISAM 表的讀操作與寫操作之間,以及寫操作之間是串行的。當(dāng)一個線程獲得對一個表的寫鎖后, 只有持有鎖的線程可以對表進(jìn)行更新操作。其他線程的讀、 寫操作都會等待,直到鎖被釋放為止。
默認(rèn)情況下,寫鎖比讀鎖具有更高的優(yōu)先級:當(dāng)一個鎖釋放時,這個鎖會優(yōu)先給寫鎖隊列中等候的獲取鎖請求,然后再給讀鎖隊列中等候的獲取鎖請求。
3.InnoDB 行鎖
- InnoDB 實現(xiàn)了以下兩種類型的行鎖:
- 共享鎖(S):允許一個事務(wù)去讀一行,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。
- 排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)取得相同數(shù)據(jù)集的共享讀鎖和排他寫鎖。
為了允許行鎖和表鎖共存,實現(xiàn)多粒度鎖機(jī)制,InnoDB 還有兩種內(nèi)部使用的意向鎖(Intention Locks),這兩種意向鎖都是表鎖:
- 意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行加行共享鎖,事務(wù)在給一個數(shù)據(jù)行加共享鎖前必須先取得該表的 IS 鎖。
- 意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加行排他鎖,事務(wù)在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的 IX 鎖。
索引失效會導(dǎo)致行鎖變表鎖。比如 vchar 查詢不寫單引號的情況。
4.加鎖機(jī)制
樂觀鎖與悲觀鎖是兩種并發(fā)控制的思想,可用于解決丟失更新問題
樂觀鎖會“樂觀地”假定大概率不會發(fā)生并發(fā)更新沖突,訪問、處理數(shù)據(jù)過程中不加鎖,只在更新數(shù)據(jù)時再根據(jù)版本號或時間戳判斷是否有沖突,有則處理,無則提交事務(wù)。用數(shù)據(jù)版本(Version)記錄機(jī)制實現(xiàn),這是樂觀鎖最常用的一種實現(xiàn)方式
悲觀鎖會“悲觀地”假定大概率會發(fā)生并發(fā)更新沖突,訪問、處理數(shù)據(jù)前就加排他鎖,在整個數(shù)據(jù)處理過程中鎖定數(shù)據(jù),事務(wù)提交或回滾后才釋放鎖。另外與樂觀鎖相對應(yīng)的,悲觀鎖是由數(shù)據(jù)庫自己實現(xiàn)了的,要用的時候,我們直接調(diào)用數(shù)據(jù)庫的相關(guān)語句就可以了。
5.鎖模式(InnoDB有三種行鎖的算法)
- 記錄鎖(Record Locks):單個行記錄上的鎖。對索引項加鎖,鎖定符合條件的行。其他事務(wù)不能修改和刪除加鎖項;
- 它會在 id=1 的記錄上加上記錄鎖,以阻止其他事務(wù)插入,更新,刪除 id=1 這一行在通過 主鍵索引 與 唯一索引 對數(shù)據(jù)行進(jìn)行 UPDATE 操作時,也會對該行數(shù)據(jù)加記錄鎖:
-- id 列為主鍵列或唯一索引列 UPDATE SET age = 50 WHERE id = 1;- 間隙鎖(Gap Locks):當(dāng)我們使用范圍條件而不是相等條件檢索數(shù)據(jù),并請求共享或排他鎖時,InnoDB會給符合條件的已有數(shù)據(jù)記錄的索引項加鎖。對于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做“間隙”。
- InnoDB 也會對這個“間隙”加鎖,這種鎖機(jī)制就是所謂的間隙鎖。
- 對索引項之間的“間隙”加鎖,鎖定記錄的范圍(對第一條記錄前的間隙或最后一條將記錄后的間隙加鎖),不包含索引項本身。其他事務(wù)不能在鎖范圍內(nèi)插入數(shù)據(jù),這樣就防止了別的事務(wù)新增幻影行。
- 間隙鎖基于非唯一索引,它鎖定一段范圍內(nèi)的索引記錄。間隙鎖基于下面將會提到的Next-Key Locking 算法,請務(wù)必牢記:使用間隙鎖鎖住的是一個區(qū)間,而不僅僅是這個區(qū)間中的每一條數(shù)據(jù)。
- 即所有在(1,10)區(qū)間內(nèi)的記錄行都會被鎖住,所有id 為 2、3、4、5、6、7、8、9 的數(shù)據(jù)行的插入會被阻塞,但是 1 和 10 兩條記錄行并不會被鎖住。
- GAP鎖的目的,是為了防止同一事務(wù)的兩次當(dāng)前讀,出現(xiàn)幻讀的情況
- 臨鍵鎖(Next-key Locks):臨鍵鎖,是記錄鎖與間隙鎖的組合,它的封鎖范圍,既包含索引記錄,又包含索引區(qū)間。(臨鍵鎖的主要目的,也是為了避免幻讀(Phantom Read)。如果把事務(wù)的隔離級別降級為RC,臨鍵鎖則也會失效。)
- Next-Key 可以理解為一種特殊的間隙鎖,也可以理解為一種特殊的算法。通過臨建鎖可以解決幻讀的問題。
- 每個數(shù)據(jù)行上的非唯一索引列上都會存在一把臨鍵鎖,當(dāng)某個事務(wù)持有該數(shù)據(jù)行的臨鍵鎖時,會鎖住一段左開右閉區(qū)間的數(shù)據(jù)。
- 需要強(qiáng)調(diào)的一點是,InnoDB 中行級鎖是基于索引實現(xiàn)的,臨鍵鎖只與非唯一索引列有關(guān),在唯一索引列(包括主鍵列)上不存在臨鍵鎖。
對于行的查詢,都是采用該方法,主要目的是解決幻讀的問題
6.select for update有什么含義,會鎖表還是鎖行還是其他
-
for update 僅適用于InnoDB,且必須在事務(wù)塊(BEGIN/COMMIT)中才能生效。
-
在進(jìn)行事務(wù)操作時,通過“for update”語句,MySQL會對查詢結(jié)果集中每行數(shù)據(jù)都添加排他鎖,其他線程對該記錄的更新與刪除操作都會阻塞。排他鎖包含行鎖、表鎖。
-
InnoDB這種行鎖實現(xiàn)特點意味著:只有通過索引條件檢索數(shù)據(jù),InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!假設(shè)有個表單 products ,里面有id跟name二個欄位,id是主鍵。
-
明確指定主鍵,并且有此筆資料,row lock
- 明確指定主鍵,若查無此筆資料,無lock
- 無主鍵,table lock
- 主鍵不明確,table lock
- 主鍵不明確,table lock
注1: FOR UPDATE僅適用于InnoDB,且必須在交易區(qū)塊(BEGIN/COMMIT)中才能生效。
注2: 要測試鎖定的狀況,可以利用MySQL的Command Mode ,開二個視窗來做測試。
7.死鎖
死鎖產(chǎn)生:
- 死鎖是指兩個或多個事務(wù)在同一資源上相互占用,并請求鎖定對方占用的資源,從而導(dǎo)致惡性循環(huán)
- 當(dāng)事務(wù)試圖以不同的順序鎖定資源時,就可能產(chǎn)生死鎖。多個事務(wù)同時鎖定同一個資源時也可能會產(chǎn)生死鎖
- 鎖的行為和順序和存儲引擎相關(guān)。以同樣的順序執(zhí)行語句,有些存儲引擎會產(chǎn)生死鎖有些不會——死鎖有雙重原因:真正的數(shù)據(jù)沖突;存儲引擎的實現(xiàn)方式。
檢測死鎖:
數(shù)據(jù)庫系統(tǒng)實現(xiàn)了各種死鎖檢測和死鎖超時的機(jī)制。InnoDB存儲引擎能檢測到死鎖的循環(huán)依賴并立即返回一個錯誤。
死鎖恢復(fù):
死鎖發(fā)生以后,只有部分或完全回滾其中一個事務(wù),才能打破死鎖,InnoDB目前處理死鎖的方法是,將持有最少行級排他鎖的事務(wù)進(jìn)行回滾。
所以事務(wù)型應(yīng)用程序在設(shè)計時必須考慮如何處理死鎖,多數(shù)情況下只需要重新執(zhí)行因死鎖回滾的事務(wù)即可。
外部鎖的死鎖檢測:
發(fā)生死鎖后,InnoDB 一般都能自動檢測到,并使一個事務(wù)釋放鎖并回退,另一個事務(wù)獲得鎖,繼續(xù)完成事務(wù)。
但在涉及外部鎖,或涉及表鎖的情況下,InnoDB 并不能完全自動檢測到死鎖, 這需要通過設(shè)置鎖等待超時參數(shù) innodb_lock_wait_timeout 來解決
死鎖影響性能:
死鎖會影響性能而不是會產(chǎn)生嚴(yán)重錯誤,因為InnoDB會自動檢測死鎖狀況并回滾其中一個受影響的事務(wù)。
在高并發(fā)系統(tǒng)上,當(dāng)許多線程等待同一個鎖時,死鎖檢測可能導(dǎo)致速度變慢。
有時當(dāng)發(fā)生死鎖時,禁用死鎖檢測(使用innodb_deadlock_detect配置選項)可能會更有效,這時可以依賴innodb_lock_wait_timeout設(shè)置進(jìn)行事務(wù)回滾。
MyISAM避免死鎖:
在自動加鎖的情況下,MyISAM 總是一次獲得 SQL 語句所需要的全部鎖,所以 MyISAM 表不會出現(xiàn)死鎖。
InnoDB避免死鎖:
為了在單個InnoDB表上執(zhí)行多個并發(fā)寫入操作時避免死鎖,可以在事務(wù)開始時通過為預(yù)期要修改的每個元祖(行)使用SELECT … FOR UPDATE語句來獲取必要的鎖,即使這些行的更改語句是在之后才執(zhí)行的。
在事務(wù)中,如果要更新記錄,應(yīng)該直接申請足夠級別的鎖,即排他鎖,而不應(yīng)先申請共享鎖、更新時再申請排他鎖,因為這時候當(dāng)用戶再申請排他鎖時,其他事務(wù)可能又已經(jīng)獲得了相同記錄的共享鎖,從而造成鎖沖突,甚至死鎖
如果事務(wù)需要修改或鎖定多個表,則應(yīng)在每個事務(wù)中以相同的順序使用加鎖語句。在應(yīng)用中,如果不同的程序會并發(fā)存取多個表,應(yīng)盡量約定以相同的順序來訪問表,這樣可以大大降低產(chǎn)生死鎖的機(jī)會
通過SELECT … LOCK IN SHARE MODE獲取行的讀鎖后,如果當(dāng)前事務(wù)再需要對該記錄進(jìn)行更新操作,則很有可能造成死鎖。
改變事務(wù)隔離級別
如果出現(xiàn)死鎖,可以用 show engine innodb status;命令來確定最后一個死鎖產(chǎn)生的原因。
返回結(jié)果中包括死鎖相關(guān)事務(wù)的詳細(xì)信息,如引發(fā)死鎖的 SQL 語句,事務(wù)已經(jīng)獲得的鎖,正在等待什么鎖,以及被回滾的事務(wù)等。據(jù)此可以分析死鎖產(chǎn)生的原因和改進(jìn)措施。
八、性能優(yōu)化
1.影響mysql的性能因素
- 業(yè)務(wù)需求對MySQL的影響(合適合度)
- 存儲定位對MySQL的影響
- 系統(tǒng)各種配置及規(guī)則數(shù)據(jù)
- 活躍用戶的基本信息數(shù)據(jù)
- 活躍用戶的個性化定制信息數(shù)據(jù)
- 準(zhǔn)實時的統(tǒng)計信息數(shù)據(jù)
- 其他一些訪問頻繁但變更較少的數(shù)據(jù)
- 二進(jìn)制多媒體數(shù)據(jù)
- 流水隊列數(shù)據(jù)
- 超大文本數(shù)據(jù)
- 不適合放進(jìn)MySQL的數(shù)據(jù)
- 需要放進(jìn)緩存的數(shù)據(jù)
- Schema設(shè)計對系統(tǒng)的性能影響
- 盡量減少對數(shù)據(jù)庫訪問的請求
- 盡量減少無用數(shù)據(jù)的查詢請求
- 硬件環(huán)境對系統(tǒng)性能的影響
2.性能分析
MySQL Query Optimizer
- MySQL 中有專門負(fù)責(zé)優(yōu)化 SELECT 語句的優(yōu)化器模塊,主要功能:通過計算分析系統(tǒng)中收集到的統(tǒng)計信息,為客戶端請求的 Query 提供他認(rèn)為最優(yōu)的執(zhí)行計劃(他認(rèn)為最優(yōu)的數(shù)據(jù)檢索方式,但不見得是 DBA 認(rèn)為是最優(yōu)的,這部分最耗費時間)
- 當(dāng)客戶端向 MySQL 請求一條 Query,命令解析器模塊完成請求分類,區(qū)別出是 SELECT 并轉(zhuǎn)發(fā)給 MySQL Query Optimize r時,MySQL Query Optimizer 首先會對整條 Query 進(jìn)行優(yōu)化,處理掉一些常量表達(dá)式的預(yù)算,直接換算成常量值。
- 并對 Query 中的查詢條件進(jìn)行簡化和轉(zhuǎn)換,如去掉一些無用或顯而易見的條件、結(jié)構(gòu)調(diào)整等。
- 然后分析 Query 中的 Hint 信息(如果有),看顯示 Hint 信息是否可以完全確定該 Query 的執(zhí)行計劃。
- 如果沒有 Hint 或 Hint 信息還不足以完全確定執(zhí)行計劃,則會讀取所涉及對象的統(tǒng)計信息,根據(jù) Query 進(jìn)行寫相應(yīng)的計算分析,然后再得出最后的執(zhí)行計劃。
MySQL常見瓶頸
- CPU:CPU在飽和的時候一般發(fā)生在數(shù)據(jù)裝入內(nèi)存或從磁盤上讀取數(shù)據(jù)時候
- IO:磁盤I/O瓶頸發(fā)生在裝入數(shù)據(jù)遠(yuǎn)大于內(nèi)存容量的時候
- 服務(wù)器硬件的性能瓶頸:top,free,iostat 和 vmstat來查看系統(tǒng)的性能狀態(tài)
性能下降SQL慢 執(zhí)行時間長 等待時間長 原因分析
- 查詢語句寫的爛
- 索引失效(單值、復(fù)合)
- 關(guān)聯(lián)查詢太多join(設(shè)計缺陷或不得已的需求)
- 服務(wù)器調(diào)優(yōu)及各個參數(shù)設(shè)置(緩沖、線程數(shù)等)
MySQL常見性能分析手段
在優(yōu)化MySQL時,通常需要對數(shù)據(jù)庫進(jìn)行分析,常見的分析手段有慢查詢?nèi)罩?#xff0c;EXPLAIN 分析查詢,profiling分析以及show命令查詢系統(tǒng)狀態(tài)及系統(tǒng)變量,通過定位分析性能的瓶頸,才能更好的優(yōu)化數(shù)據(jù)庫系統(tǒng)的性能。
- 性能瓶頸定位
我們可以通過 show 命令查看 MySQL 狀態(tài)及變量,找到系統(tǒng)的瓶頸:
Mysql> show status ——顯示狀態(tài)信息(擴(kuò)展show status like ‘XXX’)Mysql> show variables ——顯示系統(tǒng)變量(擴(kuò)展show variables like ‘XXX’)Mysql> show innodb status ——顯示InnoDB存儲引擎的狀態(tài)Mysql> show processlist ——查看當(dāng)前SQL執(zhí)行,包括執(zhí)行狀態(tài)、是否鎖表等Shell> mysqladmin variables -u username -p password——顯示系統(tǒng)變量Shell> mysqladmin extended-status -u username -p password——顯示狀態(tài)信息-
Explain(執(zhí)行計劃)
-
慢查詢?nèi)罩?/p>
MySQL 的慢查詢?nèi)罩臼?MySQL 提供的一種日志記錄,它用來記錄在 MySQL 中響應(yīng)時間超過閾值的語句,具體指運行時間超過 long_query_time 值的 SQL,則會被記錄到慢查詢?nèi)罩局小?/strong>
- long_query_time 的默認(rèn)值為10,意思是運行10秒以上的語句
- 默認(rèn)情況下,MySQL數(shù)據(jù)庫沒有開啟慢查詢?nèi)罩?#xff0c;需要手動設(shè)置參數(shù)開啟
- 查看開啟狀態(tài)
-
開啟慢查詢?nèi)罩?/p>
-
臨時配置:
也可set文件位置,系統(tǒng)會默認(rèn)給一個缺省文件host_name-slow.log
使用set操作開啟慢查詢?nèi)罩局粚Ξ?dāng)前數(shù)據(jù)庫生效,如果MySQL重啟則會失效。
- 永久配置
修改配置文件my.cnf或my.ini,在[mysqld]一行下面加入兩個配置參數(shù)
[mysqld] slow_query_log = ON slow_query_log_file = /var/lib/mysql/hostname-slow.log long_query_time = 33.性能優(yōu)化
索引優(yōu)化
- 全值匹配我最愛
- 最佳左前綴法則,比如建立了一個聯(lián)合索引(a,b,c),那么其實我們可利用的索引就有(a), (a,b), (a,b,c)
- 不在索引列上做任何操作(計算、函數(shù)、(自動or手動)類型轉(zhuǎn)換),會導(dǎo)致索引失效而轉(zhuǎn)向全表掃描
- 存儲引擎不能使用索引中范圍條件右邊的列
- 盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列一致)),減少select
- is null ,is not null 也無法使用索引
- like “xxxx%” 是可以用到索引的,like “%xxxx” 則不行(like “%xxx%” 同理)。like以通配符開頭(’%abc…’)索引失效會變成全表掃描的操作,
- 字符串不加單引號索引失效
- 少用or,用它來連接時會索引失效
- <,<=,=,>,>=,BETWEEN,IN 可用到索引,<>,not in ,!= 則不行,會導(dǎo)致全表掃描
一般性建議
- 對于單鍵索引,盡量選擇針對當(dāng)前query過濾性更好的索引
- 在選擇組合索引的時候,當(dāng)前Query中過濾性最好的字段在索引字段順序中,位置越靠前越好。
- 在選擇組合索引的時候,盡量選擇可以能夠包含當(dāng)前query中的where字句中更多字段的索引
- 盡可能通過分析統(tǒng)計信息和調(diào)整query的寫法來達(dá)到選擇合適索引的目的
- 少用Hint強(qiáng)制索引
查詢優(yōu)化
- 永遠(yuǎn)小標(biāo)驅(qū)動大表(小的數(shù)據(jù)集驅(qū)動大的數(shù)據(jù)集)
當(dāng) B 表的數(shù)據(jù)集必須小于 A 表的數(shù)據(jù)集時,用 in 優(yōu)于 exists
select * from A where exists (select 1 from B where B.id=A.id) #等價于 select * from A select * from B where B.id = A.id`order by關(guān)鍵字優(yōu)化
- order by子句,盡量使用 Index 方式排序,避免使用 FileSort 方式排序
- MySQL 支持兩種方式的排序,FileSort 和 Index,Index效率高,它指 MySQL 掃描索引本身完成排序,FileSort 效率較低;
- ORDER BY 滿足兩種情況,會使用Index方式排序;①ORDER BY語句使用索引最左前列 ②使用where子句與ORDER BY子句條件列組合滿足索引最左前列
- 盡可能在索引列上完成排序操作,遵照索引建的最佳最前綴
- 如果不在索引列上,filesort 有兩種算法,mysql就要啟動雙路排序和單路排序
-
- 雙路排序:MySQL 4.1之前是使用雙路排序,字面意思就是兩次掃描磁盤,最終得到數(shù)據(jù)
-
- 單路排序:從磁盤讀取查詢需要的所有列,按照order by 列在 buffer對它們進(jìn)行排序,然后掃描排序后的列表進(jìn)行輸出,效率高于雙路排序
- 優(yōu)化策略
-
- 增大sort_buffer_size參數(shù)的設(shè)置
-
- 增大max_lencth_for_sort_data參數(shù)的設(shè)置
GROUP BY關(guān)鍵字優(yōu)化
- group by實質(zhì)是先排序后進(jìn)行分組,遵照索引建的最佳左前綴
- 當(dāng)無法使用索引列,增大 max_length_for_sort_data 參數(shù)的設(shè)置,增大sort_buffer_size參數(shù)的設(shè)置
- where高于having,能寫在where限定的條件就不要去having限定了
數(shù)據(jù)類型優(yōu)化
MySQL 支持的數(shù)據(jù)類型非常多,選擇正確的數(shù)據(jù)類型對于獲取高性能至關(guān)重要。不管存儲哪種類型的數(shù)據(jù),下面幾個簡單的原則都有助于做出更好的選擇。
- 更小的通常更好:一般情況下,應(yīng)該盡量使用可以正確存儲數(shù)據(jù)的最小數(shù)據(jù)類型。簡單就好:簡單的數(shù)據(jù)類型通常需要更少的CPU周期。例如,整數(shù)比字符操作代價更低,因為字符集和校對規(guī)則(排序規(guī)則)使字符比較比整型比較復(fù)雜。
- 盡量避免NULL:通常情況下最好指定列為NOT NULL
總結(jié)
以上是生活随笔為你收集整理的MySQL基础总结(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL基础总结(二)
- 下一篇: MySQL高级之explain详解