https://blog.csdn.net/weixin_38003389/article/details/83746223mysql
字段請使用utf8mb4字符集linux
3.對mysql優化時一個綜合性的技術,主要包括(硬件、配置、設計、執行、規模)sql
SQL級docker
a: 表的設計合理化(符合3NF)數據庫
b: 添加適當索引(index) [四種: 普通索引、主鍵索引、惟一索引unique、全文索引]編程
e: 存儲過程 [模塊化編程,預編譯,能夠提升速度]緩存
服務器級安全
c: 分庫分表(水平分割、垂直分割)bash
d: 主從複製,讀寫分離 [寫: update/delete/add]
f: 對mysql配置優化 [配置最大併發數my.ini, 調整緩存大小,默認爲100,max_connection=1000 ]
部分數據庫鏈接池會與mysql保持長鏈接不放,因此分佈式/集羣時注意保證數據庫有充足的連接
g: mysql服務器硬件升級
h: 定時的去清除不須要的數據,定時進行碎片整理(MyISAM)
I: 將歷史數據轉移
4. 3NF
1NF: 即表的列的具備原子性,不可再分解
2NF: 表中的記錄是惟一的, 就知足2NF
3NF: 即表中不要有冗餘數據
反3NF : 可是,沒有冗餘的數據庫未必是最好的數據庫,有時爲了提升運行效率,就必須下降範式標準,適當保留冗餘數據,減小多表關聯。
5 show status/variables like 'name' 檢查配置
show status like 'uptime' ; (mysql數據庫啓動了多長時間)
show stauts like 'com_select' show stauts like 'com_insert' ...類推 update delete(顯示數據庫的查詢,更新,添加,刪除的次數)
show [session|global] status like .... 若是你不寫 [session|global] 默認是session 會話,指取出當前窗口的執行,若是你想看全部(從mysql 啓動到如今,則應該 global)
show status like 'connections';//顯示到mysql數據庫的鏈接數
show status like 'slow_queries';//顯示慢查詢次數 默認10s以上是慢查詢 推薦縮小
show global variables like 'long_query_time'; //能夠顯示當前慢查詢時間
set global slow_query_log='ON' //(臨時開啓慢查詢日誌,mysql重啓時失效)
set long_query_time=1 ;//能夠修改慢查詢時間s(重啓失效)
set global max_connections=500 ;//修改最大連接數
show variables like 'slow_query%' :slow_query_log是否開啓慢查詢日誌,1表示開啓,0表示關閉。
slow-query-log-file:新版(5.6及以上版本)MySQL數據庫慢查詢日誌存儲路徑。能夠不設置該參數,系統則會默認給一個缺省的文件host_name-slow.log
log-slow-queries :舊版(5.6如下版本)MySQL數據庫慢查詢日誌存儲路徑。能夠不設置該參數,系統則會默認給一個缺省的文件host_name-slow.log
log_queries_not_using_indexes:未使用索引的查詢也被記錄到慢查詢日誌中(可選項)。
log_output:日誌存儲方式。log_output=
'FILE'
表示將日誌存入文件,默認值是
'FILE'
。log_output=
'TABLE'
表示將日誌存入數據庫,這樣日誌信息就會被寫入到mysql.slow_log表中。MySQL數據<br>庫支持同時兩種日誌存儲方式,配置的時候以逗號隔開便可,如:log_output=
'FILE,TABLE'
。日誌記錄到系統的專用日誌表中,要比記錄到文件耗費更多的系統資源,所以對於須要啓用慢查詢日誌,又須要可以得到更高的系統性能,那麼建議優先記錄到文件。
6 慢查詢日誌
記錄超過long_query_time時間的sql語句
在默認狀況下,咱們的mysql不會記錄慢查詢,需啓動mysql時候,指定記錄慢查詢日誌 啓動指令 bin\mysqld.exe - -safe-mode - -slow-query-log [mysql5.5 能夠在my.ini指定](安全模式啓動,數據庫將操做寫入日誌,以備恢復);bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0能夠在my.ini指定]
推薦臨時開啓:set global slow_query_log =1 (mysql重啓時失效)
先關閉mysql服務,再啓動, 若是啓用了慢查詢日誌,默認把這個文件放在my.ini 文件中記錄的位置
#Path to the database root
datadir="C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/"
mysqldumpslow 慢日誌分析工具
命令:
-s 按照那種方式排序 c:訪問計數 l:鎖定時間 r:返回記錄 al:平均鎖定時間 ar:平均訪問記錄數 at:平均查詢時間 -t 是top n的意思,返回多少條數據。 -g 能夠跟上正則匹配模式,大小寫不敏感。
舉例:
獲得返回記錄最多的20個sql::mysqldumpslow -s r -t 20 /database/mysql/mysql_slow.log(日誌路徑)
獲得平均訪問次數最多的20條sql:mysqldumpslow -s ar -t 20 sqlslow.log
獲得平均訪問次數最多,而且裏面含有ttt字符的20條sql:mysqldumpslow -s ar -t 20 -g "ttt" sqldlow.log
https://blog.csdn.net/sunyuhua_keyboard/article/details/81204020
http://www.javashuo.com/article/p-ervhibgs-k.html(包含win/linux下使用)
執行結果格式
命令解析:排序(-s)按執行次數(c)倒序(-a) C:\Program Files\MySQL\MySQL Server 5.5\bin>perl mysqldumpslow.pl -s c -a c:\mysql\log\mysqlslowquery.log Reading mysql slow query log from c:\mysql\log\mysqlslowquery.log 執行次數 Count: 3 執行時間Time=0.27s (0s) 鎖定時間Lock=1.67s (1s) 發送行數Rows=1.0 (1), 執行地址root[root]@localhost 內容:select count(*) from lm_d_plan Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows=0.0 (0), 0users@0hosts C:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld, Version: 5.5.22-log (MySQL Community Server (GPL)). started with: TCP Port: 3306, Named Pipe: (null)
SQL解析順序
影響索引的最左命中。必定是解析順序在前的字段,排在索引左邊。
解析順序 : from..on..join..where..group by..having..seletc distinct..order by limit
http://www.javashuo.com/article/p-qaiuyzym-cn.html
解析過程簡述:
一、肯定主驅動表
有A,B,C三個表作join查詢。Mysql先要經過where條件推斷結果集,沒有條件則按照全表計算,從小到大依次解析表。
假設推斷後,A=10行,B=5行,C=15行 ,中間MySQL還會有一些緩存或join順序優化,同行數的看where可否命中索引等。
假定優化後解析順序 :B>A>C。肯定主驅動表=B。
二、開始解析執行,索引生效
B:做爲最小驅動表,執行where條件取得結果集1。此時where條件斷定索引命中。
A:與結果集1執行join on生成臨時表(斷定索引),where條件過濾取得結果集2。
C:與A相同,與結果集2執行join on生成臨時表,where條件過濾取得結果集3。
能夠看到索引順序,除主驅動表外都是先on再where。下面會有具體測試案例。
7 索引 (主鍵索引/惟一索引/全文索引/普通索引)
primary key 有兩個做用,一是約束做用(constraint),用來規範一個存儲主鍵和惟一性,但同時也在此key上創建了一個主鍵索引;
PRIMARY KEY 約束:惟一標識數據庫表中的每條記錄;主鍵必須包含惟一的值;主鍵列不能包含 NULL 值;每一個表都應該有一個主鍵,而且每一個表只能有一個主鍵。(PRIMARY KEY 擁有自動定義的 UNIQUE 約束)
primary key(name,age) #複合主鍵
unique key 也有兩個做用,一是約束做用(constraint),規範數據的惟一性,但同時也在這個key上創建了一個惟一索引;
UNIQUE 約束:惟一標識數據庫表中的每條記錄。UNIQUE 和 PRIMARY KEY 約束均爲列或列集合提供了惟一性的保證。(每一個表能夠有多個 UNIQUE 約束,可是每一個表只能有一個 PRIMARY KEY 約束)
unique index(`userId` ,`taskId`,`date`) #複合惟一索引
惟一索引注意 null 是能夠重複的。例如:unique index(`userId` ,`phone`),能夠重複插入不報錯:('A00001',null)。
所以在建立屬於惟一索引的列時,最好指定字段值不能爲空,在已有值爲NULL的狀況下,建立的字段不容許爲空,且默認值爲空字符。若是已經建立了默認值爲NULL的字段,則先將其update爲空字符,而後再修改成NOT NULL DEFAULT ‘’。
foreign key也有兩個做用,一是約束做用(constraint),規範數據的引用完整性,但同時也在這個key上創建了一個index;
索引的代價:佔用磁盤空間,dml操做變慢
適合建索引列:
a:字段在where,on,order,group常用
b: 該字段的內容多樣化,惟一性高(容易縮小範圍)
c: 字段內容不是頻繁變化.
使用索引的注意事項:
a.單表查詢一次只能命中一個索引。影響:查找,排序
多表查詢時經過EXPLAN能夠看到各個表的子查詢命中的索引狀況和執行順序
b.unique字段能夠爲NULL,並能夠有多NULL, 可是若是是具體內容,則不能重複
c.複合索引從左邊按順序開始匹配,注意sql解析順序,避免跨列引發索引失效。
把可能索引失效的列儘量放在KEY最後
使用最頻繁、惟一性高的,解析順序靠前的字段 放在最左。
建立key(a,b,c)後,不用再建立(a,b),(a)索引
d.BTREE全覆蓋索引,查詢時不用回表
i. join on 條件字段索引,= 左右哪一個字段循環頻率高,創建索引 。
定位驅動表: 左外聯左表驅動,右外聯右表驅動,內聯自動小表驅動。內聯能夠經過表自身大小和EXPLAN解析select掃描的行數來判斷那個表爲驅動表。
通常狀況:被驅動表on條件必定要加索引(條件容許也可兩表都創建索引)。由於被驅動表通常是主表循環的內嵌套循環,執行頻率高。
且where條件中儘可能可以過濾一些行將驅動表變得小一點
l.主鍵自帶索引,會自動加到複合索引的最右側
J.TEXT,長字符串,若須要查詢則能夠創建前綴索引。創建前先觀察不一樣長度前綴的區分度,肯定前綴長度
索引失效總結: 命中不連續,類型轉換,列計算,null值判斷,負向(否)條件,in/or,like ‘%a’,範圍查詢右邊key(自身也可能失效)。某些狀況是機率事件,不必定百分百觸發。
e.對於使用like的查詢,查詢若是是 ‘%aaa’ 不會使用到索引 (索引失效)
f.某列是範圍查詢,其索引右邊列沒法使用索引。(索引失效,多範圍條件注意)
例如:key(a,b,c) => where a=1 and b>0 and c<0 => 只會用到key(a,b)或key(a) 有不肯定性
g.若是條件中有or,要求or包含的全部字段都必須創建索引,其中一個有索引也無效 (索引失效)
h.避免在where條件中進行 null值判斷、in、負向條件(!=、<>、not in、not like、not exists ) 這會使索引失效,因此把這些列放在複合索引最後位置,或是優化爲其餘形式(例如:用left join + id=null 代替not in )
j.不要在索引字段作操做(計算,函數,類型轉換等),會引發索引失效。例如:where a+1=1
k.顯式/隱式類型轉換,會引發索引失效 例如:where name=1
H.可使用全覆蓋索引挽救索引失效
例如:select * from user where name like '%a%',其必然索引失效。
能夠創建key(name,id),改變SQL爲: select name,id from user where name like '%a%' 這樣雖然索引失效,可是能夠挽救爲use index。
8.sql語句的優化
避免索引失效
select:
a.可使用關聯來替代子查詢。由於使用join,MySQL不須要在內存中建立臨時表。(5.5及如下)
b.確保關聯查詢 on/using 條件命中索引,內聯順序的第二個表建索引,左外聯建左表,右外聯建右表
c.left join 儘量小表在左驅動大表,join至關於for循環嵌套,次數少的循環放在最外層。inner join mysql會自動優化。也能夠嘗試用straight join 代替inner join,強制驅動表。
條件 「=」 小表字段在左邊
d.避免使用select *,減小IO負擔。(測試字段多時,時間消耗有可能成倍增加)
e.發現掃描行數遠大於結果,則考慮優化查詢:使用覆蓋索引/修改表結構/複雜查詢分割多個小查詢
f.儘量使用索引覆蓋掃描select
g.select ..from table where in/exists (子查詢),主查詢結果ROW大用IN反之用exist
h.left join where id != null 能夠代替 not in () 。或是先插入臨時表再delete
join、between 能夠代替 in ()。in中元素不要太多,不然必須被代替。
i.合理運用臨時表,好比有一張整年表,如今只須要一個月數據,且這個數據後邊要反覆查詢/處理,則先插入臨時表,之後就不用處理整年表啦
j.避免使用過多的join 關聯表。於Mysql來講,是存在關聯緩存的,緩存的大小能夠由join_buffer_size參數進行設置
在Mysql中,對於同一個SQL多關聯(join)一個表,就會多分配一個關聯緩存,若是在一個SQL中關聯的表越多,
所佔用的內存也就越大。若是程序中大量的使用了多表關聯的操做,同時join_buffer_size設置的也不合理的狀況下,就容易形成服務器內存溢出的狀況,就會影響到服務器數據庫性能的穩定性同時對於關聯操做來講,會產生臨時表操做,影響查詢效率
Mysql最多容許關聯61個表,建議不超過5個
k.拆分大sql變爲小sql。大SQL:邏輯上比較複雜,須要佔用大量CPU進行計算的SQL。MySQL 一個SQL只能使用一個CPU進行計算。SQL拆分後能夠經過並行執行來提升處理效率
L.不會有重複值時使用UNION ALL 。UNION 會把兩個結果集的全部數據放到臨時表中後再進行去重操做, UNION ALL 不會再對結果集進行去重操做
group:
a.在使用group by 分組查詢是默認分組後,還會排序,可能會下降速度。
在group by 後面增長 order by null 就能夠防止排序.
b.group by/order by 只涉及一個表的字段,才能使用索引。group by 能夠拆分紅子查詢,從而使其只涉及一個表。
c.用join關聯條件作group by條件,效率更高
limit:
a.儘量使用索引覆蓋掃描select
b.order by 命中索引
c.當只須要一條結果時手動limit 1,能夠有效減小掃描量。
d.大表分頁優化。例如:表有主鍵ID自增,每頁有10條數據,想顯示第二頁數據,傳統思路limit 11,10。優化思路 where id>10 limit 10。
order by :
a.避免使用select *
b.選擇單路(4以後默認)/雙路排序方法,設置max_length_for_sort_data擴大排序緩衝區
c.複合索引,按照解析順序不要跨列
d,排序字段,同升同降 order by a desc,b desc
優化舉例:
例1:
order by 舉例對比:有索引 key(a,b,c,d)
where +order by 從左命中不要跨列
select a,b,c,d from table where a=1 and d=1 and c=1 and b=1
(using index全覆蓋查詢, 實際用到 key(a,b,c,d))
select a,b,c,d from table where a=1 and b=1 and d=1 order by c
(using index,using where 回表查詢 ,由於從左命中d跨列致使d沒法用到索引 ,實際使用 key(a,b))
select a,b,c,d from table where a=1 and d=1 order by c
(using index,using where,using fliesort 回表查詢+文件排序:由於從左命中orderby跨列 key(a))
select a,b,c,d from table where a=1 and d=1 order by b,c
(using index,using where :對比上個例子沒有using fliesort,由於where +orderby沒有索引跨列,可是由key_len可知道,實際使用只有 key(a),只是避免了文件排序)
例2:
Sql解析順序影響索引命中,in()可能出現索引失效
select b from table where a=1 and c in (1,2) order by c
key(a,c,b) 效果最好,受Sql解析順序影響,b放在where條件以後
索引中將c放在a以後,即便c in ()索引失效, a 索引仍是有效
例3:
多表JOIN 解析對比索引命中。請先閱讀上面的"sql解析順序"
表user_zhw: 列( userid,zhwid,beizhu ) union_key(userid,zhwid) 當前 7 rows 表zhwdoc: 列(id ,name) KEY(id) 當前 3 rows select * from user_zhw join zhwdoc on zhwdoc.id=user_zhw.zhwid where zhwdoc.name ='prouser' and user_zhw.userid=1
只執行前兩行:解析
同ID由上至下執行,sql解析順序規則(見上面),先鎖定結果可能最少的表,由於只執行前兩行無where,可是zhwdoc總行數少因此其爲主驅動表。zhwdoc先執行where過濾由於沒where全部ALL掃描。以後on條件關聯user_zhw表沒有命中索引ALL掃描。掃描行數3+7。
執行前三句:解析
同ID由上至下執行。經過where條件肯定zhwdoc結果集較小做爲主驅動表。
zhwdoc先執行where過濾,沒有命中索引ALL掃描。以後on條件關聯user_zhw表沒有命中索引ALL掃描。掃描行數3+7。
所有執行:解析
同ID由上至下執行。 經過where條件肯定user_zhw命中索引其結果集較小做爲主驅動表。
user_zhw先執行where過濾且命中部分索引(len)。以後on條件關聯zhwdoc表索引命中。掃描行數1+1。
例4: 誤區
表user_zhw: 列( userid,zhwid,beizhu ) union_key(userid,zhwid) 當前 7 rows select userid,zhwid from user_zhw where zhwid=1
上面where條件應該沒法命中索引,可是解釋結果命中了所有索引union_key長度,可是看掃描行數爲全表掃描。 此處命中的索引是由於Using index,既索引全覆蓋,select字段不用回表查詢。where條件並無命中,因此仍是全表掃描。多表join時也要特別注意,不要只看key列,必定要以rows爲準。可是也說明在where沒法命中狀況下 ,全覆蓋索引能稍微彌補
9.EXPLAN
a.EXPLAN是近似結果,可能與真相相差甚遠,且只能解釋select
b.id,type,key,row,extra幾個字段比較關鍵
id:表示執行順序,由大到小執行,id相同時由上到下執行
type:ALL/index/range/ref/eq_ref/const/system/null 效率由低到高,通常以range/ref爲目標
ALL:按行順序全表掃描。通常百萬以上出現ALL則必須優化
index:按索引順序全表掃描,避免了排序。缺點是承擔按索引順序讀取的開銷
range:範圍掃描。有範圍的索引掃描。(between,><,in,or 且命中索引)
ref:索引訪問/查找。返回全部匹配當個索引列的結果。
例如:select name from T where name="a" (name命中索引)
key:實際使用索引(where\on\select),只能命中一個。5.0後有索引合併
多表查詢時經過EXPLAN (id)能夠看到各個表的子查詢命中的索引狀況和執行順序
key_len:判斷使用索引前幾個字段,例如 KEY(A,B,C) 使用到(A,B,C)和(A,B)長度不一樣
row:預估掃描的行數(直觀檢驗)
extra:
using index :使用覆蓋索引(不回表)
using where :可能部分受益於索引(需回表)
using temporary :需優化,排序使用臨時表(group by 未命中索引)
using fliesort :需優化,文件排序 IO消耗(order by 未命中索引,where +orderby 從左命中不要跨列)
using join buffer : 需優化。
10 存儲引擎
myisam,請必定記住要定時進行碎片整理
innoDB vs myisam:
InnoDB 支持事物+行級鎖+支持外鍵+支持MVCC,不支持全文索引
11 鎖
1 加行鎖(命中索引):互斥鎖X,其餘線程不能再在此行上任何鎖,其餘線程可讀不可寫,直到當前線程提交事務。insert /update /select ...for update
共享鎖S,全部可讀不可寫,共享鎖能夠疊加,以前的全部共享鎖都解鎖才能上互斥鎖。select ...lock in share mode
commit 時解除鎖
不管經過哪一個索引命中此行,只要此行被鎖住,其餘線程都不能更新此行
2 沒有命中索引,行鎖會轉爲表鎖
坑1:update table set name='sw' where name=1 ,假設有KEY(name),可是name=1發生類型轉換,致使索引失效,執 行update產生表鎖
表鎖要等待全部行鎖+表鎖解鎖
3 間隙鎖:mysql爲範圍內不存在的行加鎖
例如:update table set name='hh' where id<=3; 有key(id)。即便當前表中尚未id=2的行,mysql也會鎖住id in (1,2,3) 三行內容。在update未提交以前,讀/寫/插入id=3的數據,就會阻塞
4 樂觀鎖(版本號 or 時間戳 or 臨界條件)
提升數據庫併發能力,避免超買超減等問題。本質上是CAS,要保證比較和賦值是原子性操做
好比: 在事務A中使用 update spkc set shl=shl-1 where id=1 and shl>0,判斷受影響rows決定是否扣減成功是否向下執行。事務A執行update會上鎖(注意命中索引,不然會上表鎖),其餘事務須要等待事務A提交再執行update。
https://blog.csdn.net/shanchahua123456/article/details/86571038
5 避免死鎖,加速事務提交
http://www.javashuo.com/article/p-osrltxbr-bn.html
https://825635381.iteye.com/blog/2339434
5.1 以固定的順序訪問表和行,這樣就避免了交叉等待鎖的情形
5.2 大事務拆小、縮短事務提交時間、避免事務中有複雜邏輯/遠程調用。
必定要保證事務方法不要無休止的不提交事務。好比方法中等待http/遠程響應,或複雜邏輯等狀況致使不能提交。
5.3 在同一個事務中,儘量作到一次鎖定所須要的全部資源。
5.4 爲表添加合理的索引,命中索引上行鎖。避免表鎖,不容易死鎖
5.5 避免gap鎖
5.6 併發插入出現duplicate key重複鍵異常時,當前事務會默認加上S鎖。這時當前事務再去申請X鎖,就會死鎖。
能夠查看死鎖日誌
查看鎖表
方法一 慢查詢日誌
方法二 MYSQL中執行
http://www.javashuo.com/article/p-oulolrez-ee.html
-- 查看那些表鎖到了 show OPEN TABLES where In_use > 0; --In_use列表示有多少線程正在使用某張表,Name_locked表示表名是否被鎖 -- 查看進程號 show processlist; --刪除進程 kill 1085850; --查看正在鎖的事務 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; --查看等待鎖的事務 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
12 日誌
mysql日誌的種類,通常來講,日誌有五種,分別爲:
錯誤日誌:-log-err (記錄啓動,運行,中止mysql時出現的信息)
二進制日誌:-log-bin (記錄全部更改數據的語句,還用於複製,同步,恢復數據庫用)
查詢日誌:-log (所有記錄創建的客戶端鏈接和執行的語句,量大,不建議生產中使用)
慢查詢日誌: -log-slow-queries (記錄全部執行超過long_query_time秒的全部查詢)
查詢當前日誌記錄的情況:
mysql>show variables like 'log_%';(是否啓用了日誌)
mysql> show master status;(怎樣知道當前的日誌)
mysql> show master logs;(顯示二進制日誌的數目)
binlog
http://www.javashuo.com/article/p-yhnowzxb-m.html
http://www.javashuo.com/article/p-hgvzgbhe-be.html
show variables like 'log_%'; (查看日誌開啓和保存路徑)
show binary logs;(現有的binlog名字)
show global variables like "binlog%";(查看模式)
經過上邊指令鎖定日誌文件路徑
在linux中mysql執行(解析時間較長,注意縮短datetime)
docker須要進入運行的mysql容器執行
mysqlbinlog --start-datetime='2019-01-01 00:00:00' --stop-datetime='2019-06-18 23:01:01' -d 庫名 /var/lib/mysql/binlog.000003
若打印的SQL語句爲亂碼,則須要base64解析 --base64-output=decode-rows
mysqlbinlog --base64-output=decode-rows -v --start-datetime='2019-01-01 00:00:00' --stop-datetime='2019-06-18 23:01:01' -d 庫名 /var/lib/mysql/binlog.000003
執行SQL:update user set beactive='n' where id=1 (user 表有三個字段)
能夠看到update-log顯示了全部字段的新舊狀態。
13 安全
1 防止sql注入,因此最好使用預編譯SQL執行 #{}
例如:注入 "or 1=1 " 做爲條件欺騙
2 字符儘可能使用單引號。尤爲是sql_mode='ANSI_QUOTES'時,雙引號會當識別符處理,引發條件丟失/賦值錯誤
14 大量數據操做
過大數據的(100萬)批量寫操做要分批屢次操做 1.大批量操做可能會致使嚴重的主從延遲 2. binlog日誌爲row格式時會產生大量的日誌 大批量寫操做會產生大量日誌,特別是對於row格式二進制數據而言,因爲在row格式中會記錄每一行數據的修改,咱們一次修改的數據越多, 產生的日誌量也就會越多,日誌的傳輸和恢復所須要的時間也就越長,這也是形成主從延遲的一個緣由 3. 避免產生大事務操做 大批量修改數據,必定是在一個事務中進行的,這就會形成表中大批量數據進行鎖定,從而致使大量的阻塞,阻塞會對MySQL的性能產生很是大的影響 特別是長時間的阻塞會佔滿全部數據庫的可用鏈接,這會使生產環境中的其餘應用沒法鏈接到數據庫,所以必定要注意大批量寫操做要進行分批 4.對於大表的修改使用pt-online-schema-change 1.原理: 會在原表的結構上建造一個新表 複製數據 2.避免延遲,修改時鎖表 5.禁止super權限濫用 6.數據帳號鏈接最小
15 mysql緩存機制
http://www.javashuo.com/article/p-ecfshsol-bk.html
mysql自身也有緩存機制,能夠很大提升重複查詢的執行效率
表碎片整理
http://www.javashuo.com/article/p-tydujnyo-bc.html
OPTIMIZE TABLE table_name 會鎖住整張表進行整理,且時間可能很長