學(xué)習(xí)記錄之MySQL索引及調(diào)優(yōu)
MySQL 索引簡介
1.1?:索引誕生的背景是怎樣的?
????假如數(shù)據(jù)庫表中只有10條記錄,我們可以一條條的進(jìn)行查詢。假如有500萬條記錄呢,從假如還是一條條去查詢可能需要的時間就會比較長,此時索引就誕生了。
1.2?:我們所說的索引是什么?
????官方給出的解釋是,索引(Index)是一種數(shù)據(jù)結(jié)構(gòu)。通俗的說,假如我們將一本書看成是一張表,那么索引就相當(dāng)于書的目錄,為了方便查找書中的內(nèi)容,可以通過對內(nèi)容建立索引形成目錄。通過目錄可以快速定位要查找的內(nèi)容。
????對于數(shù)據(jù)庫而言,可以維護(hù)一個滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些結(jié)構(gòu)以某種方式引用數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實現(xiàn)數(shù)據(jù)的快速查找。這就是索引。
1.3?:索引有什么特點呢?
????索引(Index)的優(yōu)點是可以加大數(shù)據(jù)的檢索速度。缺點是索引需要占用物理空間(默認(rèn)是以數(shù)據(jù)頁進(jìn)行存儲),而且對表中的數(shù)據(jù)進(jìn)行增加、刪除和修改時,索引也要動態(tài)維護(hù),這樣會降低增/改/刪的執(zhí)行效率。
?????如果沒有索引,我們從數(shù)據(jù)庫表中查詢記錄時,必須從第一行開始,讀取整個表進(jìn)行查找,表越大,成本就越高。如果表中有相關(guān)列的索引,就可以快速確定要在數(shù)據(jù)文件中間查找的位置,而不必查看所有數(shù)據(jù),比按順序讀取每一行快得多。
????MySQL索引對表中指定列進(jìn)行排序后可以另外保存,保存的內(nèi)容中包含著對數(shù)據(jù)表里所有記錄的引用指針,用于快速查找具有特定值的行。但不是所有表上都可以建索引,要根據(jù)表使用的存儲引擎來看,有的存儲引擎支持建索引,有的不支持。
1.4?:索引的應(yīng)用原則有哪些?
????索引使用總有一些原則:
?????1) 對經(jīng)常在where、連接條件中出現(xiàn)的列考慮創(chuàng)建索引。
?????2) 對選擇性比較好的列必要時建索引。
?????比如用戶表中,身份證的列具有不同值,選擇性很好,索引被使用時特別高效;姓名列,選擇性較好,索引被使用時也比較高效;性別列,只含有男和女,選擇性很差,對此列建索引就沒有多大用處。
?????3) 不要過度創(chuàng)建索引。
????索引不是越多越好,每個索引都要占用磁盤空間,并會降低DML操作的性能。另外MySQL 在生成執(zhí)行計劃時,過多的索引也會加重優(yōu)化器的工作,甚至可能干擾優(yōu)化器選擇不到最好的索引。
MySQL索引類型分析
2.1?:索引是怎樣分類的?
????說到索引的分類,可從三個維度進(jìn)行分析:
?? 邏輯應(yīng)用維度
1)?? 主鍵索引:主鍵索引是一種特殊的唯一索引,不允許有空值(唯一索引允許值為空)。
2)?? 普通索引或者單列索引:每個索引只包含單個列,一個表可以有多個單列索引。
3)?? 多列索引(復(fù)合索引、聯(lián)合索引):復(fù)合索引指多個字段上創(chuàng)建的索引,只有在查詢條件中使用了創(chuàng)建索引時的第一個字段,索引才會被使用。使用復(fù)合索引時遵循最左前綴集合
4)?? 唯一索引:表中字段的值不能出現(xiàn)重復(fù)的。
5)???空間索引:空間索引是對空間數(shù)據(jù)類型的字段建立的索引,空間索引只能在存儲引擎為MYISAM的表中創(chuàng)建。
?? 物理存儲維度
1)?? 聚簇索引(clustered index):在InnoDB中一張表只有一個聚簇索引(一般可以理解為主鍵索引),索引和數(shù)據(jù)是在一起的。
2)?? 非聚簇索引(non-clustered index):也叫輔助索引( secondary index), 非聚簇索引是索引和數(shù)據(jù)分離的。
?? 數(shù)據(jù)存儲結(jié)構(gòu)維度
1)?? B+樹索引。(最重要) 2) Hash索引。
3) Full-Text全文索引。 4) R-Tree索引。
2.2: 如何創(chuàng)建索引?
????普通索引:普通索引為 MySQL 中的基本索引類型,沒有什么限制,允許在定義索引的列中插入重復(fù)值和空值,純粹為了查詢數(shù)據(jù)更快一點。創(chuàng)建普通索引的方式如下:
????唯一索引:唯一索引與普通索引類似,只是索引列中的值必須是唯一的,但是允許為空值。
????主鍵索引:主鍵索引是一種特殊的唯一索引,索引列中的值必須是唯一的,并且不允許有空值。
組合索引:組合索引又稱為復(fù)合索引,在表中的多個字段組合上創(chuàng)建的索引,組合索引的使用,需要遵循最左前綴原則(最左匹配原則)。一般情況下,建議使用組合索引代替單列索引主鍵索引除外)
說明:
1)? 復(fù)合索引的字段是有順序的,在查詢使用時要按照定義時索引字段的順序使用,例如 select * from test where name=xxx and phone=xxx;匹配(name,age)組合索引,不匹配(age,name)索引。
如果表已經(jīng)建立了(col1,col2),就沒有必要再單獨建立(col1);
全文索引:只能在文本類型 CHAR,VARCHAR,TEXT 類型字段上創(chuàng)建全文索引。字段長度較大時,如果創(chuàng)建普通索引,在進(jìn)行 like 模糊查詢時效率比較低,這時可以創(chuàng)建全文索引。全文搜索時候,全文索引一般很少使用,數(shù)據(jù)量比較少或者并發(fā)度低的時候可以用。但是數(shù)據(jù)量大或者并發(fā)度高的時候一般是用專業(yè)的工具 lucene,es,solr。
和常用的 like 模糊查詢不同,全文索引有自己的語法格式,可以使用 MATCH() ...AGAINST 語法執(zhí)行全文搜索,例如:
說明:
1)? 在MySQL5.6以前的版本,只有MyISAM存儲引擎支持全文索引,從MySQL5.6開始,
MyISAM和InnoDB存儲引擎都已經(jīng)支持。
2)? 全文索引必須在字符串、文本字段上建立。
3)? 全文索引的字段值必須在最小和最大字符之間時才會生效。
4)? 全文索引的字段值會進(jìn)行切詞處理,例如b+aaa,切分成b和aaa。
5)? 全文索引查詢默認(rèn)使用的是等值匹配,例如a匹配a,不會匹配ab,ac。如果希望匹配可以在布爾模式下搜索a*;
如何查詢?nèi)乃饕囊?guī)則?(innodb 存儲引擎默認(rèn)是大于 3 個字符小于 84 個字符使用全
文)
?前綴索引:在文本類型如CHAR,VARCHAR,TEXT類列上創(chuàng)建索引時,可以指定索引列的長度,但是數(shù)值類型不能指定。
2.3?:如何查看索引?
????刪除索引之前我們可以基于如下方式查看索引
2.4?:如何刪除指定索引?
MySQL索引結(jié)構(gòu)分析
3.1?:需求分析
????我們知道正確應(yīng)用索引、可以提高數(shù)據(jù)查詢的性能。那我們?nèi)粘9ぷ鞯牡臄?shù)據(jù)查詢可以將其分為兩大類:
1.?? 等值查詢:根據(jù)某個值查找數(shù)據(jù)。例如:
2.???范圍查詢:根據(jù)某個范圍區(qū)間查找數(shù)據(jù)。例如
我們在基于查詢設(shè)計索引時,需要考慮時間和空間兩個因素:
1)?? 在執(zhí)行時間方面,我們希望通過索引,查詢數(shù)據(jù)的時間盡可能小。
2)? ?在存儲空間方面,我們希望索引不要消耗太多的內(nèi)存空間和磁盤空間。
3.2: 數(shù)據(jù)結(jié)構(gòu)分析
????我們首先要知道一點,索引(Index)是在存儲引擎(storage engine)層面實現(xiàn)的,不是所有的存儲引擎,都支持所有的索引類型,即使是不同存儲引擎支持同一索引類型,她們的實現(xiàn)和行為也可能會有差異。
????常用的索引數(shù)據(jù)結(jié)構(gòu):Hash表,二叉樹,平衡二叉查找樹(紅黑樹是一個近似平衡二叉樹),B樹,B+樹。
3.3?:Hash 表結(jié)構(gòu)分析
Java中的HashMap就是Hash表結(jié)構(gòu),以鍵值對的方式存儲數(shù)據(jù)。例如:

????我們使用Hash表存儲表數(shù)據(jù),Key可以存儲索引列,Value可以存儲行記錄或者行磁盤地址。Hash表在等值查詢時效率很高,時間復(fù)雜度為O(1);但是不支持范圍快速查找,范圍查找時還是只能通過掃描全表方式。
????數(shù)據(jù)庫的InnoDB引擎提供了自適應(yīng)索引,為了提高查詢效率,InnoDB存儲引擎會監(jiān)控表上各個索引頁的查詢,當(dāng) InnoDB 注意到某些索引值訪問頻繁時,會在內(nèi)存中基于 B+Tree索引再創(chuàng)建一個哈希索引,使得內(nèi)存中的B+Tree索引具備哈希索引的功能,即能夠快速定值訪問頻繁訪問的索引頁。
????自適應(yīng)哈希索引的建立使得 InnoDB 存儲引擎自動根據(jù)索引頁訪問頻率和模式自動的為某些熱點頁建立哈希索引來加速訪問,另外InnoDB自適應(yīng)Hash索引的功能,用戶只能選擇開啟或關(guān)閉,服務(wù)進(jìn)行人工干預(yù)
3.4?:Tree 結(jié)構(gòu)索引分析
????MySQL中的InnoDB和MyISAM,都使用B+Tree的數(shù)據(jù)結(jié)構(gòu),但如如何理解B+Tree結(jié)構(gòu),我們可以從二叉查找樹進(jìn)行分析。
?二叉查找樹:二叉查找樹(Binary Search Trees),每個節(jié)點最多有2個分叉,左子樹和右子樹,數(shù)據(jù)順序左小右大,也就是左子樹的值小于根的值,右子樹的值大于根的值。例如:

????在上面的圖中,假如查找 72,則只需要三次查找即可,查詢效率可以得到明顯提升。但問題來了,是不是任何數(shù)據(jù)都可以基于二叉查找樹結(jié)構(gòu)提高查詢效率呢?答案是否定的,例如,基于表中的id自增主鍵值,構(gòu)建的二叉查找樹,這個樹就會退化為了一個單項鏈表,其結(jié)構(gòu)如圖所示。假如此時我們查找5這個節(jié)點,就進(jìn)行全表掃描,并不會提高查詢效率。

平衡二叉樹:平衡二叉樹(Balanced binary search trees)是采用二分法思維,平衡二叉查找樹除了具備二叉樹的特點,最主要的特征是樹的左右兩個子樹的層級最多相差1。

????平衡二叉樹在插入、刪除數(shù)據(jù)時,通過左旋/右旋操作保持二叉樹的平衡,不會出現(xiàn)左子樹很高、右子樹很矮的情況。這樣我們查詢數(shù)據(jù)的時間復(fù)雜度就穩(wěn)定了。
????使用平衡二叉查找樹,查詢的性能接近于二分查找法,時間復(fù)雜度是 O(log2n)。查詢 id=25,只需要兩次IO。
????那我們使用AVL樹作為索引是不是就可以了呢,答案是否定的。我們知道MySQL中數(shù)據(jù)是存儲在磁盤上的,每次進(jìn)行數(shù)據(jù)查詢會將磁盤里的數(shù)據(jù)讀取到內(nèi)存中,對磁盤IO是非常耗時的。在表數(shù)據(jù)量大時,查詢性能就會很差。所以我們優(yōu)化的重點就是盡量減少磁盤 IO 操作。訪問二叉樹的每個節(jié)點就會發(fā)生一次IO,如果想要減少磁盤IO操作,就需要盡量降低樹的高度。那如何降低樹的高度呢?
?B-樹:為了解決平衡二叉樹浪費磁盤空間以及 IO 次數(shù)過多的問題,我們在一個節(jié)點中多存儲一些 數(shù)據(jù),之前我們放一個,現(xiàn)在我們放多個。由此,B 樹就誕生了。注意這里的 B 樹中的 B 代 表平衡(balance),而不是二叉(binary)。例如:

B樹是一種多叉平衡查找樹,一顆m階B-樹,要么為空樹,要么滿足如下特性:
1)?? 樹中每個節(jié)點最多有m棵子樹(m階為樹中節(jié)點的最大分支數(shù))。
2)?? 若根節(jié)點不是葉子,則至少有兩棵子樹。
3)?? 所有非葉子節(jié)點包含n個關(guān)鍵字和n+1棵子樹。
4)?? 所有葉子節(jié)點都在同一層。
????說明,B樹不支持范圍查詢的快速查找,每次查詢都需要從根節(jié)點進(jìn)行多次遍歷,查詢效率有待提高。還有,如果data存儲的是行記錄,行的大小隨著列數(shù)的增多,占空間會變大。這時,一個頁中可存儲的數(shù)據(jù)量就會變少,樹相應(yīng)就會變高,磁盤 IO 次數(shù)就會變大。
B+樹(B-樹Plus)?
在B樹基礎(chǔ)上,MySQL在B樹的基礎(chǔ)上繼續(xù)改造,使用B+樹構(gòu)建索引。B+樹和B-樹最主要的區(qū)別在于非葉子節(jié)點是否存儲數(shù)據(jù)的問題。

1)?? 一棵m階的B+樹每個節(jié)點最多可以有m個key;
2)?? B+樹的所有key都在葉子節(jié)點中有序排列;
3)?? B+樹的所有非葉子節(jié)點都是為了查找到葉子節(jié)點。(非葉子節(jié)點不存儲數(shù)據(jù))
4)?? B+樹的葉子節(jié)點處于同一層,相鄰的葉子節(jié)點通過雙向鏈表進(jìn)行連接。(與B-樹不同)
為什么Mysql使用B+樹而不是B樹作為索引?
1)?? B樹的葉子節(jié)點和非葉子節(jié)點都會存儲數(shù)據(jù),這樣會導(dǎo)致非葉子節(jié)點可以保存的指針數(shù)量減少,數(shù)據(jù)量比較大時,樹的高度可能就會比較大,樹越高,導(dǎo)致磁盤 IO 的次數(shù)就會變多,查詢的性能就會變低。
2)?? B+樹非葉子節(jié)點不存儲數(shù)據(jù),只存儲索引 key,這樣可以存儲 key就會比較多, key越多可以分的叉就越多,樹的高度就不會太高,這樣磁盤io就會比較少,性能就會比較好。
3)?? B+樹對于新增與修改節(jié)點的效率也是比較高的,這與B樹相同;
4)?? 在葉子節(jié)點引入了鏈表,增加范圍查詢的效率。
為什么Mysql使用B+樹而不是B樹作為索引?
1)?? B樹的葉子節(jié)點和非葉子節(jié)點都會存儲數(shù)據(jù),這樣會導(dǎo)致非葉子節(jié)點可以保存的指針數(shù)量減少,數(shù)據(jù)量比較大時,樹的高度可能就會比較大,樹越高,導(dǎo)致磁盤 IO 的次數(shù)就會變多,查詢的性能就會變低。
2)?? B+樹非葉子節(jié)點不存儲數(shù)據(jù),只存儲索引 key,這樣可以存儲 key就會比較多, key越多可以分的叉就越多,樹的高度就不會太高,這樣磁盤io就會比較少,性能就會比較好。
3)?? B+樹對于新增與修改節(jié)點的效率也是比較高的,這與B樹相同;
4)?? 在葉子節(jié)點引入了鏈表,增加范圍查詢的效率。
?3.5?:聚簇索引和非聚簇索引?
????聚簇索引和非聚簇索引:B+Tree 的葉子節(jié)點存放主鍵索引值和行記錄就屬于聚簇索引;如果索引值和行記錄分開存放就屬于非聚簇索引。
????主鍵索引和輔助索引:B+Tree 的葉子節(jié)點存放的是主鍵字段值就屬于主鍵索引。如果存放的是非主鍵值就屬于輔助索引(二級索引)。
在 InnoDB 引擎中,主鍵索引采用的就是聚簇索引結(jié)構(gòu)存儲。
1)? 聚簇索引(聚集索引)
????聚簇索引是一種數(shù)據(jù)存儲方式, InnoDB 的聚簇索引就是按照主鍵順序構(gòu)建 B+Tree 結(jié)構(gòu)。 B+Tree 的葉子節(jié)點就是行記錄,行記錄和主鍵值緊湊地存儲在一起。 這也意味著
InnoDB 的主鍵索引就是數(shù)據(jù)表本身,它按主鍵順序存放了整張表的數(shù)據(jù),占用的空間就是整個表數(shù)據(jù)量的大小。通常說的主鍵索引就是聚集索引。
????InnoDB 的表要求必須要有聚簇索引。如果表定義了主鍵,則主鍵索引就是聚簇索引。如果表沒有定義主鍵,則第一個非空 unique 列作為聚簇索引,否則 InnoDB 會建一個隱藏的 row-id 作為聚簇索引。
2)? 輔助索引
????InnoDB 輔助索引,也叫作二級索引,是根據(jù)索引列構(gòu)建 B+Tree 結(jié)構(gòu)。但在 B+Tree 的葉子節(jié)點中只存了索引列和主鍵的信息。二級索引占用的空間會比聚簇索引小很多, 通常創(chuàng)建輔助索引就是為了提升查詢效率。一個表 InnoDB 只能創(chuàng)建一個聚簇索引,但可以創(chuàng)建多個輔助索引。
????與InnoDB表存儲不同,MyISAM 數(shù)據(jù)表的索引文件和數(shù)據(jù)文件是分開的,被稱為非聚簇索
引結(jié)構(gòu)。
?4 索引分析與優(yōu)化
4.1: Explain 是什么?
????MySQL 提供了一個Explain命令,它可以對select語句進(jìn)行分析,并輸出select執(zhí)行時的詳細(xì)信息,開發(fā)人員可以基于這些信息進(jìn)行有針對性的優(yōu)化。
? ? select_type 表示查詢的類型。常用的值如下:
1)?? SIMPLE : 表示查詢語句不包含子查詢或 union
2)?? PRIMARY:表示此查詢是最外層的查詢
3)?? UNION:表示此查詢是 union 的第二個或后續(xù)的查詢
4)?? DEPENDENT UNION:union 中的第二個或后續(xù)的查詢語句,使用了外面查詢結(jié)果
5)?? UNION RESULT:union 的結(jié)果
6)?? SUBQUERY:SELECT 子查詢語句
7)?? DEPENDENT SUBQUERY:SELECT 子查詢語句依賴外層查詢的結(jié)果。
? ? type 表示查詢數(shù)據(jù)的方式。
type是一個比較重要的一個屬性,通過它可以判斷出查詢是全表掃描還是基于索引的部分掃描。常用屬性值如下,從上至下效率依次增強。
1)?? ALL:表示全表掃描,性能最差。
2)?? index:表示基于索引的全表掃描,先掃描索引再掃描全表數(shù)據(jù)。
3)?? range:表示使用索引范圍查詢。使用 >、>=、<、<=、in 等等。
4)?? ref:表示使用非唯一索引進(jìn)行單值查詢。
5)?? eq_ref:一般情況下出現(xiàn)在多表 join 查詢,表示前面表的每一個記錄,都只能匹配后面表的一行結(jié)果。
6)?? const:表示使用主鍵或唯一索引做等值查詢,常量查詢。
7)?? NULL:表示不用訪問表,速度最快。
?? possible_keys
表示查詢時能夠使用到的索引。注意并不一定會真正使用,顯示的是索引名稱。
?? key
表示查詢時真正使用到的索引,顯示的是索引名稱。
?? rows
MySQL 查詢優(yōu)化器會根據(jù)統(tǒng)計信息,估算 SQL 要查詢到結(jié)果需要掃描多少行記錄。原則上 rows 是越少效率越高,可以直觀的了解到 SQL 效率高低。
?? key_len
表示查詢使用了索引的字節(jié)數(shù)量??梢耘袛嗍欠袢渴褂昧私M合索引。
key_len 的計算規(guī)則如下:
1)?? 字符串類型
字符串長度跟字符集有關(guān):latin1=1、gbk=2、utf8=3、utf8mb4=4 char(n):n*字符集長度 varchar(n):n * 字符集長度 + 2字節(jié)
2)?? 數(shù)值類型
TINYINT:1個字節(jié)
SMALLINT:2個字節(jié)
MEDIUMINT:3個字節(jié)
INT、FLOAT:4個字節(jié)
BIGINT、DOUBLE:8個字節(jié)
3)?? 時間類型
DATE:3個字節(jié)
TIMESTAMP:4個字節(jié)
DATETIME:8個字節(jié)
4)?? 字段屬性
NULL 屬性占用 1 個字節(jié),如果一個字段設(shè)置了 NOT NULL ,則沒有此項。
? ?? Extra
Extra 表示很多額外的信息,各種操作會在 Extra 提示相關(guān)信息,常見幾種如下:
?1)?? Using where
表示查詢需要通過索引回表查詢數(shù)據(jù)。
2)?? Using index
表示查詢需要通過索引,索引就可以滿足所需數(shù)據(jù)。
3)?? Using filesort
表示查詢出來的結(jié)果需要額外排序,數(shù)據(jù)量小在內(nèi)存,大的話在磁盤,因此有 Using filesort 建議優(yōu)化。?
4)?? Using temprorary
查詢使用到了臨時表,一般出現(xiàn)于去重、分組等操作。
4.2?:什么是回表查詢?
? ??我們知道InnoDB 索引有聚簇索引和輔助索引。聚簇索引的葉子節(jié)點存儲行記錄,InnoDB 必須要有,而且只有一個。輔助索引的葉子節(jié)點存儲的是主鍵值和索引字段值,通過輔助索引無法直接定位行記錄,通常情況下,需要掃碼兩遍索引樹。先通過輔助索引定位主鍵值,然后再通過聚簇索引定位行記錄,這就叫做回表查詢,它的性能比掃一遍索引樹低。
4.3?:什么是覆蓋索引?
????覆蓋索引指的是在一棵索引樹上就可以獲取 SQL 所需要的所有數(shù)據(jù),而不需要執(zhí)行回表查詢。在 MySQL中, explain 輸出結(jié)果的 Extra 字段為 Using index 時,能夠觸發(fā)索引覆蓋。假如我們需要實現(xiàn)索引覆蓋,可以考慮將被查詢的字段,建立到組合索引。
4.4?:什么是最左前綴匹配?
????復(fù)合索引使用時遵循最左前綴原則,也就是最左優(yōu)先,如果查詢條件中最左邊的列和復(fù)合索引最左邊的列的順序匹配,查詢就會使用到索引,如果不匹配則索引將失效。例如你在(username,phone,email)三個字段上建立了索引,查詢條件中也按此順序進(jìn)行定義的則會應(yīng)用索引,假如查詢條件中寫的是 phone=’1111’ and email=’t@tedu.cn’則會索引失效。
4.5?:有哪些常見問題?
?? MySQL 在使用 like 模糊查詢時,索引能不能起作用?
MySQL在使用Like模糊查詢時,索引是可以被使用的,只有把 % 字符寫在后面才會使用到索引。
?? 如果 MySQL 表的某一列含有 NULL 值,那么包含該列的索引是否有效?
????對null值是否走索引要結(jié)合具體版本以及使用的引擎來確定,例如在mysql5.7 存儲引擎為InnoDB中, 我們看到兩個sql都是走索引的,并不會因為 is null而不走索引,所以字段為null并不會影響sql走索引。但是,還是建議無論索引列還是其他列,都設(shè)置成非 null,通過設(shè)置默認(rèn)值解決 null 值問題。如果把索引列一些值設(shè)置為 null,也是允許的,但是寫sql 時候就要用到 is null 和 is not null來進(jìn)行篩選數(shù)據(jù),這僅僅是語法的需要適配,但并不影響正確的走索引。
如何對 Order by 語句進(jìn)行優(yōu)化
1)???? 假如是單個字段,直接添加索引。
2)???? 假如是多個字段,對多個字段按使用順序添加組合索引。
3)???? 對于先等值查詢再排序的語句,可以通過在條件字段和排序字段添加聯(lián)合索引來優(yōu)化此類排序語句。
4)???? 去掉 select 列表中不需要返回的字段。
5)???? 修改數(shù)據(jù)庫參數(shù)值(例如 sort_buffer_size,max_length_for_sort_data)
對于 group by 語句的優(yōu)化,如果只要分組,沒有排序需求的話,可以加 order by null 禁止排序。
如何對 MySQL 的分頁查詢進(jìn)行優(yōu)化
?????讓排序時返回的字段盡可能少,所以可以讓排序和分頁操作先查出主鍵,然后根據(jù)主鍵查到對應(yīng)的記錄,例如:
如何進(jìn)行 Join 優(yōu)化?
1)???? 關(guān)聯(lián)字段加索引
2)???? 小表驅(qū)動大表
3)???? 使用臨時表
說明:有時因為某條關(guān)聯(lián)查詢只是臨時查一次,如果再去添加索引可能會浪費資源,那么有什么辦法優(yōu)化呢?
創(chuàng)建臨時表,把驅(qū)動表數(shù)據(jù)放到臨時表,然后在臨時表中的關(guān)聯(lián)字段上添加索引,然后通過臨時表來做關(guān)聯(lián)查詢。