[數(shù)據(jù)庫][mysql]: 索引優(yōu)化

為什么要優(yōu)化mysql
mysql 性能下降SQL慢、執(zhí)行時間長、等待時間長
原因:
1.查詢語句寫的爛
2.索引失效
  單值
  復(fù)合
3.關(guān)聯(lián)查詢太多join(設(shè)計缺陷或不得已的需求)
4.服務(wù)器調(diào)優(yōu)及各個參數(shù)設(shè)置
從幾個方面優(yōu)化
成本由低到高,效果卻由高到低:SQL及索引 –> 數(shù)據(jù)庫表結(jié)構(gòu) –> 系統(tǒng)配置 –> 硬件
常見的jion鏈接

常見的jion鏈接

1 A、B兩表共有
select * from tbl_emp a inner join tbl_dept b on a.deptId = b.id;
2 A、B兩表共有+A的獨有
select * from tbl_emp a left join tbl_dept b on a.deptId = b.id;
3 A、B兩表共有+B的獨有
select * from tbl_emp a right join tbl_dept b on a.deptId = b.id;
4 A的獨有
select * from tbl_emp a left join tbl_dept b on a.deptId = b.id where b.id is null;
5 B的獨有
select * from tbl_emp a right join tbl_dept b on a.deptId = b.id where a.deptId is null; #B的獨有
6 AB全有
#MySQL Full Join的實現(xiàn) 因為MySQL不支持FULL JOIN,下面是替代方法
#left join + union(可去除重復(fù)數(shù)據(jù))+ right join
SELECT * FROM tbl_emp A LEFT JOIN tbl_dept B ON A.deptId = B.id
UNION
SELECT * FROM tbl_emp A RIGHT JOIN tbl_dept B ON A.deptId = B.id
7 A的獨有+B的獨有
SELECT * FROM tbl_emp A LEFT JOIN tbl_dept B ON A.deptId = B.id WHERE B.`id` IS NULL
UNION
SELECT * FROM tbl_emp A RIGHT JOIN tbl_dept B ON A.deptId = B.id WHERE A.`deptId` IS NULL;
1253382-20171018162601521-1841819198.png
如何優(yōu)化mysql
1.觀察,至少跑1天,看看生產(chǎn)的慢SQL情況
  2.開啟慢查詢?nèi)罩?,設(shè)置閥值,比如超過5秒鐘的就是慢SQL,并將它抓取出來。
  3.explain+慢SQL分析
  4.show profile
  5.運維經(jīng)理 Or DBA, 進(jìn)行SQL數(shù)據(jù)庫服務(wù)器的參數(shù)調(diào)優(yōu)。
總結(jié)
  1.慢查詢的開啟并捕獲
  2.explain+慢SQL分析
  3.show profile查詢SQL在MySQL服務(wù)器里面的執(zhí)行細(xì)節(jié)和生命周期情況
  4.SQL數(shù)據(jù)庫服務(wù)器的參數(shù)調(diào)優(yōu)。

索引簡介

是什么
MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)
  可以得到索引的本質(zhì):索引是數(shù)據(jù)結(jié)構(gòu)
  可簡單理解為“排好序的快速查找數(shù)據(jù)結(jié)構(gòu)”

數(shù)據(jù)本身之外,數(shù)據(jù)庫還維護(hù)著一個滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式指向數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)上實現(xiàn)高級查找算法,這種數(shù)據(jù)結(jié)構(gòu)就是索引。

  一般來說索引本身也很大,不可能全部存儲在內(nèi)存中,因此 索引往往以索引文件的形式存儲在磁盤上
  我們平常所說的索引,如果沒有特別指明,都是B樹(多路搜索樹,并不一定是二叉的)結(jié)構(gòu)組織的索引。其中聚集索引、次要索引、覆蓋索引、復(fù)合索引、前綴索引、唯一索引默認(rèn)都是使用B+樹索引,統(tǒng)稱索引。當(dāng)然,除了B+樹之外,還有哈希索引。
優(yōu)劣勢
優(yōu)勢:
  類似大學(xué)圖書館建書目索引,提高數(shù)據(jù)檢索的效率,降低數(shù)據(jù)庫的IO成本
  通過索引列對數(shù)據(jù)進(jìn)行排序,降低數(shù)據(jù)排序的成本,降低了CPU的消耗

劣勢:
  實際上索引也是一張表,該表保存了主鍵與索引字段,并指向?qū)嶓w表的記錄,所以索引列也是要占用空間的。
  雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進(jìn)行insert,update和delete。因為更新表時,MySQL不僅要保存數(shù)據(jù),還要保存一下索引文件每次更新添加索引列的字段,都會調(diào)整因為更新所帶來的鍵值變化后的索引信息。
  索引只是提高效率的一個因素,如果你的MySQL有大數(shù)據(jù)量的表,就需要花時間 研究建立最優(yōu)秀的索引,或優(yōu)化查詢語句。
mysql索引結(jié)構(gòu)
主要有BTree索引、Hash索引、full-text全文索引、R-Tree索引。下面主要分析BTree索引
  備注:先說下,在MySQL文檔里,實際上是把B+樹索引寫成了BTREE,
  B+樹是一個平衡的多叉樹,從根節(jié)點到每個葉子節(jié)點的高度差值不超過1,而且同層級的節(jié)點間有指針相互鏈接。
  在B+樹上的常規(guī)檢索,從根節(jié)點到葉子節(jié)點的搜索效率基本相當(dāng),不會出現(xiàn)大幅波動,而且基于索引的順序掃描時,也可以利用雙向指針快速左右移動,效率非常高。
btree.png
初始化介紹
一顆b+樹,淺藍(lán)色的塊稱之為一個磁盤塊,可以看到每個磁盤塊包含幾個數(shù)據(jù)項(深藍(lán)色所示)和指針(黃色所示),如磁盤塊1包含數(shù)據(jù)項17和35,包含指針P1, P2, P3, P1表示小于17的磁盤塊,P2表示在17和35之間的磁盤塊,P3表示大于35的磁盤塊。
  真實的數(shù)據(jù)存在于葉子節(jié)點即3,5,9,19…
  非葉子節(jié)點只不存儲真實的數(shù)據(jù),只存儲指引搜索方向的數(shù)據(jù)項,如17,35并不真實存在于數(shù)據(jù)表中
查找過程
如果要查找數(shù)據(jù)項29,那么首先會把磁盤塊1由磁盤加載到內(nèi)存,此時發(fā)生一次IO,在內(nèi)存中用二分查找確定29在17和35之間,鎖定磁盤塊1的P2指針,內(nèi)存時間因為非常短(相比于磁盤的IO)可以忽略不計。
  通過磁盤塊1的P2指針的磁盤地址把磁盤塊3由磁盤加載到內(nèi)存,發(fā)生第二次IO, 29在26和30之前,鎖定磁盤塊3的P2指針。
  通過指針加載磁盤塊8到內(nèi)存,發(fā)生第三次IO,同時內(nèi)存中做二分查找找到29,結(jié)束查詢,總計三次IO。

使用索引時機

1.哪些情況需要創(chuàng)建索引
  1).主鍵自動建立唯一索引
  2).頻繁作為查詢查詢條件的字段應(yīng)該創(chuàng)建索引
  3).查詢中與其它表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
  4).頻繁更新的字段不適合創(chuàng)建索引
  5).where條件里用不到的字段不創(chuàng)建索引
  6).單鍵/組合索引的選擇問題(在高并發(fā)下傾向創(chuàng)建組合索引)
  7).查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度
  8).查詢中統(tǒng)計或者分組字段

2.哪些情況不要創(chuàng)建索引
  1).表記錄太少
  2).經(jīng)常增刪改的表(因為不僅要保存數(shù)據(jù),還要保存一下索引文件)
  3).數(shù)據(jù)重復(fù)且分布平均的表字段,因此應(yīng)該只為最經(jīng)常查詢和最經(jīng)常排序的數(shù)據(jù)列建立索引。
  注意:如果某個數(shù)據(jù)列包含許多重復(fù)的內(nèi)容,為它建立索引就沒有太大的實際效果。

索引優(yōu)化

Join語句的優(yōu)化
二張表
  性能優(yōu)化:left join是由左邊決定的,左邊一定都有,所以右邊是我們的關(guān)鍵點,建立索引要建右邊邊。當(dāng)然如果索引在左邊,可以用右連接。

1
2
select * from atable  
left join btable  on atable.aid=btable.bid;   // 最好在bid上建索引
結(jié)論:
  盡可能減少Join語句中的NestedLoop的循環(huán)次數(shù):“永遠(yuǎn)用小結(jié)果集驅(qū)動大的結(jié)果集”
避免索引失效
2.最佳左前綴法則:如果索引了多列,要尊守最左前綴法則,指的是查詢從索引的最左前列開始并且不跳過索引中的列。
  3.不在索引列上做任何操作(計算、函數(shù)、(自動or手動)類型轉(zhuǎn)換),會導(dǎo)致索引失效而轉(zhuǎn)向全表掃描。
  4.存儲引擎不能使用索引中范圍條件右邊的列。
  如這樣的sql: select * from user where username='123' and age>20 and phone='1390012345',其中username, age, phone都有索引,只有username和age會生效,phone的索引沒有用到。
  5.盡量使用覆蓋索引(只訪問索引的查詢(索引列和查詢列致)),如select age from user減少select *
  6.mysql在使用不等于(!= 或者 <>)的時候無法使用索引會導(dǎo)致全表掃描。
  7.is null, is not null 也無法使用索引。
  8.like 以通配符開頭(‘%abc..’)mysql索引失效會變成全表掃描的操作。
  所以最好用右邊like 'abc%'。如果兩邊都要用,可以用select age from user where username like '%abc%',其中age是索引列
  假如index(a,b,c), where a=3 and b like 'abc%' and c=4,a能用,b能用,c不能用
  9.字符串不加單引號索引失效
  10.少用or,用它來連接時會索引失效
  11.盡量避免子查詢,而用join
一般性建議
對于單鍵索引,盡量選擇針對當(dāng)前query過濾性更好的索引
  在選擇組合索引的時候,當(dāng)前Query中過濾性最好的字段在索引字段順序中,位置越靠前越好
  在選擇組合索引的時候,盡量選擇可以能夠包含當(dāng)前query中的where子句中更多字段的索引
  盡可能通過分析統(tǒng)計信息和調(diào)整query的寫法來達(dá)到選擇合適索引的目的。
left/right join注意
1).on與 where的執(zhí)行順序
  ON 條件(“A LEFT JOIN B ON 條件表達(dá)式”中的ON)用來決定如何從 B 表中檢索數(shù)據(jù)行。如果 B 表中沒有任何一行數(shù)據(jù)匹配 ON 的條件,將會額外生成一行所有列為 NULL 的數(shù)據(jù),在匹配階段 WHERE 子句的條件都不會被使用。僅在匹配階段完成以后,WHERE 子句條件才會被使用。它將從匹配階段產(chǎn)生的數(shù)據(jù)中檢索過濾。
  所以我們要注意:在使用Left (right) join的時候,一定要在先給出盡可能多的匹配滿足條件,減少Where的執(zhí)行。如:
2).注意ON 子句和 WHERE 子句的不同
--------------------------------------------------------------------------------------
mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id   | weight | exist |
+----+--------+------+--------+-------+
|  1 |    100 | NULL |   NULL |  NULL |
|  2 |    200 |    2 |     22 |     0 |
|  3 |    300 | NULL |   NULL |  NULL |
|  4 |    400 | NULL |   NULL |  NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)
 
mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
|  2 |    200 |  2 |     22 |     0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)
--------------------------------------------------------------------------------------
  從上可知,第一條查詢使用 ON 條件決定了從 LEFT JOIN的 product_details表中檢索符合的所有數(shù)據(jù)行。第二條查詢做了簡單的LEFT JOIN,然后使用 WHERE 子句從 LEFT JOIN的數(shù)據(jù)中過濾掉不符合條件的數(shù)據(jù)行。

查詢截取分析

查詢優(yōu)化
1.永遠(yuǎn)小表驅(qū)動大表
在java程序里,兩個for循環(huán),循環(huán)次數(shù)不管誰先誰后都是兩者次數(shù)相乘。
  但在mysql的語句中,一定要小表驅(qū)動大表,因為小表跟Mysql連接和釋放數(shù)量少
如in與exists
select * from A where id in (select id form B)
等價于
for select id from B
for select * from A where A.id=B.id
結(jié)論:當(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) // 這里的1用任何常量都行
等價于
for select * from A
for select * from B where B.id=A.id
結(jié)論:當(dāng)A表的數(shù)據(jù)集必須小于B表的數(shù)據(jù)集時,用in優(yōu)于exists。
注意:A表與B表的ID字段應(yīng)建立索引
  exists通用語法select ... from table where exists (subquery)
  該語法可以理解為:將主查詢的數(shù)據(jù),放到子查詢中做條件驗證,根據(jù)驗證結(jié)果(true或false)來決定主查詢的數(shù)據(jù)結(jié)果是否得以保留。
提示:
  1).exists(subquery)只返回true或false, 因此子查詢中select *也可以是select 1或select 'X', 官方說法是實際執(zhí)行會忽略select 清單,因此沒有區(qū)別。
  2).exists 子查詢的實際執(zhí)行過程可能經(jīng)過了優(yōu)化而不是我們理解上的逐條對比,如果擔(dān)憂效率問題,可進(jìn)行實際檢驗。
  3).exists 子查詢往往也可以用條件表達(dá)式、其他子查詢或者JOIN來替代,何種最優(yōu)需要具體問題具體分析。
2.order by 關(guān)鍵字優(yōu)化
1).order by子句,盡量使用index方式排序,避免使用FileSort方式排序
  MySQL支持二種方式的排序,F(xiàn)ileSort和Index,Index效率高,它指MySQL掃描索引本身完成排序。FileSort方式效率較低。(用explain可以在extra字段里看到Using index/filesort)
  Order By滿足兩種情況,會使用Index方式排序
   a.Order by語句使用索引最左前列
   b.使用where子句與Order by子句條件組合滿足索引最左前列。
  
  2).盡可能在索引列上完成排序操作,遵照索引建的最佳左前綴
  3).如果不在索引列上,fileSort有兩種算法:mysql就要啟動雙路排序和單路排序
  雙路排序:MySQL4.1之前是使用雙路排序,字面意思就是 兩次掃描磁盤,最終得到數(shù)據(jù),讀取行指針和orderby列,對他們進(jìn)行排序,然后掃描已經(jīng)排序好的列表,按照列表中的值重新從列表中讀取對應(yīng)的數(shù)據(jù)輸出。從磁盤取排序字段,在buffer進(jìn)行排序,再從磁盤取其他字段。取一批數(shù)據(jù),要對磁盤進(jìn)行了兩次掃描,眾所周知,I/O是很耗時的,所以在mysql4.1后,出現(xiàn)了改進(jìn)算法,就是單路排序
  單路排序:從磁盤讀取查詢需要的所有列,按照order by列在buffer對它們進(jìn)行排序,然后掃描排序后的列表進(jìn)行輸出,它的效率更快一些,避免了第二次讀取數(shù)據(jù)。并且把隨機IO變成了順序IO,但是它會使用更多的空間,因為它把每一行都保存在內(nèi)存中了。
  結(jié)論及引申出的問題:由于單路是后出的,總體而言好過雙路,但是單路也有問題。

單路的問題
  在sort_buffer中,方法B比方法A要多占用很多空間,因為方法B是把所有字段都取出,所以有可能取出的數(shù)據(jù)的總大小超出了sort_buffer的容量,導(dǎo)致每次只能取sort_buffer容量大小的數(shù)據(jù),進(jìn)行排序(創(chuàng)建tmp文件,多路合并),排完再取sort_buffer容量大小,再排…..從而多次IO.
  本來想省一次IO操作,反而導(dǎo)致了大量的I/O操作,反而得不償失。

  4).參數(shù)調(diào)優(yōu)
  增大sort_buffer_size參數(shù)的設(shè)置
  增大 max_length_for_sort_data 參數(shù)的設(shè)置

參數(shù)設(shè)置,提高order by 的速度
  1.order by 時select * 是一個大忌,最好只Query需要,這點非常重要。在這里影響的是:
    a).當(dāng)Query 的字段大小總和小于 max_length_for_sort_data ,而且排序字段不是text|blob類型時,會用改進(jìn)后的算法 – 單路排序;否則用老算法–多路排序
    b).兩種算法算法的數(shù)據(jù)都有可能超出 sort_buffer 的容量,超出之后,會創(chuàng)建tmp文件進(jìn)行合并排序,導(dǎo)致多次I/O, 但是用單路排序算法的風(fēng)險會更大一些,所以要提高 sort_buffer_size
  2.嘗試提高 sort_buffer_size
    不管用哪種算法,提高這個參數(shù)都會提高效率,當(dāng)然,要根據(jù)系統(tǒng)的能力去提高,因為這個參數(shù)是針對每個進(jìn)程的。
  3.嘗試提高 max_length_for_sort_data
    提高這個參數(shù),會增加用改進(jìn)算法的概率。但如果設(shè)的太高,數(shù)據(jù)總?cè)萘砍?sort_buffer_size 的概率增大,明顯癥狀是高的磁盤I/O活動和低的處理器使用率。

  5).總結(jié)
  MySql兩種排序方式:文件排序(filesort)或掃描有序索引排序(index)
  MySql能為排序與查詢使用相同的索引
---------------------------------------------------------
Y a_b_c(a, b, c)
order by 能使用索引最左前綴
- order by a
- order by a, b
- order by a desc, c desc
如果where使用索引的最左前綴定義為常量,則order by 能使用索引
- where a = const order by b, c
- where a = const and b = const order by c
- where a = const order by b,c
- where a = const and b > const order by b, c
不能使用索引進(jìn)行排序
- order by a asc, b desc, c desc  /* 排序不一致 */
- where g = const order by b, c   /* 丟失a索引  */
- where a = const order by c      /* 丟失b索引  */
- where a = const order by a, d   /* d不是索引的一部分  */
- where a in (..) order by b, c   /* 對于排序來說,多個相等條件也是范圍查詢(in 也是范圍查詢)??!  */
---------------------------------------------------------
3.group by 關(guān)鍵字優(yōu)化
基本與 order by 優(yōu)化一致
  1).group by 實質(zhì)是先排序后分組,遵照索引建的最佳左前綴
  2).當(dāng)無法使用索引列,增大 max_length_for_sort_data 參數(shù)的設(shè)置 + 增大sort_buffer_size參數(shù)的設(shè)置
  3).where高于having,能寫在where限定的條件就不要去having限定了。

慢查詢?nèi)罩?/h3>

1.是什么
MySql的慢查詢?nèi)罩臼荕ySQL提供的一種日志記錄,它用來記錄在MySQL中響應(yīng)時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢?nèi)罩局?  long_query_time 的默認(rèn)值為10,意思是運行10秒以上的語句。
  由它來查看哪些SQL超出了我們的最大忍耐時間值,比如一條sql執(zhí)行超過5秒種,我們就算慢SQL,希望能收集超過5秒的sql,結(jié)合之前explain進(jìn)行全面分析。   
2.怎么用
1.說明
  默認(rèn)情況下,MySQL數(shù)據(jù)庫沒有開啟慢查詢?nèi)罩?,需要我們手動來設(shè)置這個參數(shù)。
  當(dāng)然,如果不是調(diào)優(yōu)需要的話,一般不建議啟動該參數(shù),因為開啟慢查詢?nèi)罩緯蚨嗷蛏賻硪欢ǖ男阅苡绊憽B樵內(nèi)罩局С謱⑷罩居涗泴懭胛募?
2.查看是否開啟及如何開啟
  默認(rèn):show variables like '%slow_query_log%';
  開啟:set global show_query_log=1;,這個 只對當(dāng)前數(shù)據(jù)庫生效,如果MySQL重啟后則會失效。如果要永久生效,必須修改配置文件my.cnf(其他系統(tǒng)變量也是如此)

3.開啟慢查詢后,什么樣的SQL才會記錄到慢查詢?nèi)罩纠锩婺兀?  這個是由參數(shù)long_query_time控制,默認(rèn)情況下long_query_time的值為10秒,
  命令:``show variables like ‘long_query_time%;’??梢允褂妹钚薷?,也可以在my.cnf參數(shù)里面修改。
  假如運行時間正好等于 long_query_time 的情況,并不會被記錄。也就是說,在mysql源碼里是 判斷>long_query_time,而非>=.
3.日志分析工具 mysqldumpslow
在生產(chǎn)環(huán)境中,如果要手工分析日志,查找、分析SQL,顯然是個體力活,MySQL提供了日志分析工具 mysqldumpslow
查看 mysqldumpslow 的幫助信息:mysqldumpslow --help
  s: 表示按何種方式排序
  c: 訪問次數(shù)
  l: 鎖定時間
  r: 返回記錄
  t: 查詢時間
  al: 平均鎖定時間
  ar: 平均返回記錄數(shù)
  at: 平均查詢時間
  t: 返回前面多少條的數(shù)據(jù)
  g: 后邊搭配一個正則匹配模式,大小寫不敏感的。


得到返回記錄集最多的10個SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/show.log
得到訪問次數(shù)最多的10個SQL
mysqldumpslow -s c -t 10 /var/lig/mysql/show.log
得到按照時間排序的前10條里面含有左連接的查詢語句
mysqldumpslow -s t -t 10 -g "left join" /var/lig/mysql/show.log
另外建議在使用這些命令時結(jié)構(gòu) | 和more使用,否則有可能出現(xiàn)爆屏情況
mysqldumpslow -s r -t 10 /var/lig/mysql/show.log | more
4.show profile
這個是sql分析最強大的
  默認(rèn)情況下,參數(shù)處于關(guān)閉狀態(tài),并保存最近15次的運行結(jié)果

1.是什么
  是mysql提供可以用來分析當(dāng)前會話中語句執(zhí)行的資源消耗情況??梢杂糜赟QL的調(diào)優(yōu)的測量

2.分析步驟
  1).是否支持,看看當(dāng)前的mysql版本是否支持
   show variables like 'profiling%'
  2).開啟功能,默認(rèn)是關(guān)閉,使用前需要開啟
   set profiling=on
  3).運行SQL
   select * from emp group by id%10 limit 1500000
   select * from emp group by id%20 order by 5
  4).查看結(jié)果,show profiles

----------------------------------------------------------------------------------------------------------
mysql> SHOW PROFILES;
+----------+----------+-------------------------------------------------------+
| Query_ID | Duration | Query                                                 |
+----------+----------+-------------------------------------------------------+
|        1 | 2.000088 | select * from emp group by id%10 limit 1500000        |
|        2 | 1.000136 | select * from emp group by id%20 order by 5           |
----------------------------------------------------------------------------------------------------------
  5).診斷SQL,show profile cpu, block io for query 2 后的數(shù)字是 show profiles 里的query_id
參數(shù)備注:
  all: 顯示所有的開銷信息
  block io: 顯示塊IO相關(guān)開銷
  context switches: 上下文切換相關(guān)開銷
  cpu: 顯示CPU相關(guān)開銷信息
  ipc: 顯示發(fā)送和接收相關(guān)開銷信息
  memory: 顯示內(nèi)存相關(guān)開銷信息
  page faults: 顯示頁面錯誤相關(guān)開銷信息
  source: 顯示和source_function, source_file, souce_line相關(guān)的開銷信息
  swaps: 顯示交換次數(shù)相關(guān)開銷的信息

  6).日常開發(fā)需要注意的結(jié)論
  出現(xiàn)下一個情況,就很危險了。
   converting HEAP to MyISAM 查詢結(jié)果太長,內(nèi)存都不夠用了往磁盤上搬了。
   Creating tmp table 創(chuàng)建臨時表:copy數(shù)據(jù)到臨時表,用完再刪除
   Copying to tmp table on disk 把內(nèi)存中臨時表復(fù)制到磁盤,很危險?。。?   locaked
5.全局查詢?nèi)罩?/h5>
永遠(yuǎn)不要在生產(chǎn)環(huán)境上打開,測試時可以
1、配置啟用

1
2
3
4
5
6
7
8
9
在mysql的my.cnf中,設(shè)置如下:
# 開啟
general_log=1
# 記錄日志文件的路徑
general_log_file=/path/logfile
# 輸出格式
log_output=FILE
  
2、編碼啟用
mysql> set global general_log=1;
mysql> set global log_output='TABLE';
# 此后,你所編寫的sql語句,將會記錄到mysql庫里的general_log表。
# 可以用下面的命令查看
mysql> select * from mysql.general_log;
數(shù)據(jù)庫表結(jié)構(gòu)優(yōu)化
1.選擇合適的數(shù)據(jù)類型
  數(shù)據(jù)類型的選擇,重點在于 合適,如何選擇合適的數(shù)據(jù)類型?
  1.使用可以存下你的數(shù)據(jù)的最小的數(shù)據(jù)類型
  2.使用簡單的數(shù)據(jù)類型,int要比varchar類型在mysql處理上簡單
  3.盡可能的使用not null定義字段
  4.盡量少用text類型,非用不可最好考慮分表。

待補充

1、mysql鎖機制
2、explain分析
3、常見通用join查詢分析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容