1、什麼影響了數據庫查詢速度前端
一、影響數據庫查詢速度的四個因素mysql
二、風險分析程序員
QPS:Queries Per Second意思是「每秒查詢率」,是一臺服務器每秒可以相應的查詢次數,是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。sql
TPS:是TransactionsPerSecond的縮寫,也就是事務數/秒。它是軟件測試結果的測量單位。客戶機在發送請求時開始計時,收到服務器響應後結束計時,以此來計算使用的時間和完成的事務個數。數據庫
Tips:最好不要在主庫上數據庫備份,大型活動前取消這樣的計劃。緩存
三、網卡流量:如何避免沒法鏈接數據庫的狀況安全
四、大表帶來的問題性能優化
1)大表的特色服務器
2)大表的危害網絡
①慢查詢:很難在短期內過濾出須要的數據
查詢字區分度低 -> 要在大數據量的表中篩選出來其中一部分數據會產生大量的磁盤io -> 下降磁盤效率
②對DDL影響:
創建索引須要很長時間:
修改表結構須要長時間的鎖表:會形成長時間的主從延遲('480秒延遲')
3)如何處理數據庫上的大表
分庫分表把一張大表分紅多個小表。
難點:
五、大事務帶來的問題
1) 什麼是事務
2)事務的ACID屬性
①原子性(atomicity):所有成功,所有回滾失敗。銀行存取款。
②一致性(consistent):銀行轉帳的總金額不變。
③隔離性(isolation):
隔離性等級:
查看系統的事務隔離級別:show variables like '%iso%';
開啓一個新事務:begin;
提交一個事務:commit;
修改事物的隔離級別:set session tx_isolation='read-committed';
④持久性(DURABILITY):從數據庫的角度的持久性,磁盤損壞就不行了
redo log機制保證事務更新的一致性和持久性。
3)大事務
運行時間長,操做數據比較多的事務。
風險:鎖定數據太多,回滾時間長,執行時間長。
解決思路:
2、什麼影響了MySQL性能
一、影響性能的幾個方面
二、MySQL體系結構
分三層:客戶端->服務層->存儲引擎
三、InnoDB存儲引擎
MySQL5.5及以後版本默認的存儲引擎:InnoDB。
1)InnoDB使用表空間進行數據存儲
show variables like 'innodb_file_per_table
.frm :是服務器層面產生的文件,相似服務器層的數據字典,記錄表結構。
2)(MySQL5.5默認)系統表空間與(MySQL5.6及之後默認)獨立表空間
強烈創建對Innodb使用獨立表空間,優化什麼的會更方即可控。
3)系統表空間的錶轉移到獨立表空間中的方法
或者Alter table一樣能夠的轉移,可是沒法回收系統表空間中佔用的空間。
四、InnoDB存儲引擎的特性
1)特性一:事務性存儲引擎及兩個特殊日誌類型:Redo Log和Undo Log
Redo Log:實現事務的持久性(已提交的事務)。
Undo Log:未提交的事務,獨立於表空間,須要隨機訪問,能夠存儲在高性能io設備上。
Undo日誌記錄某數據被修改前的值,能夠用來在事務失敗時進行rollback;Redo日誌記錄某數據塊被修改後的值,能夠用來恢復未寫入data file的已成功事務更新的數據。
2)特性二:支持行級鎖
五、什麼是鎖
1)鎖
2)鎖類型
3)鎖的粒度
MySQL的事務支持不是綁定在MySQL服務器自己,而是與存儲引擎相關。
將table_name加表級鎖命令:lock table table_name write; 寫鎖會阻塞其它用戶對該表的‘讀寫’操做,直到寫鎖被釋放:unlock tables;
4)阻塞和死鎖
六、如何選擇正確的存儲引擎
參考條件:
總結:Innodb大法好。
注意:儘可能別使用混合存儲引擎,好比回滾會出問題在線熱備問題。
七、配置參數
1)內存配置相關參數
sort_buffer_size #定義了每一個線程排序緩存區的大小,MySQL在有查詢、須要作排序操做時纔會爲每一個緩衝區分配內存(直接分配該參數的所有內存);
join_buffer_size #定義了每一個線程所使用的鏈接緩衝區的大小,若是一個查詢關聯了多張表,MySQL會爲每張表分配一個鏈接緩衝,致使一個查詢產生了多個鏈接緩衝;
read_buffer_size #定義了當對一張MyISAM進行全表掃描時所分配讀緩衝池大小,MySQL有查詢須要時會爲其分配內存,其必須是4k的倍數;
read_rnd_buffer_size #索引緩衝區大小,MySQL有查詢須要時會爲其分配內存,只會分配須要的大小。
注意:以上四個參數是爲一個線程分配的,若是有100個鏈接,那麼須要×100。
2)如何爲緩存池分配內存
Innodb_buffer_pool_size,定義了Innodb所使用緩存池的大小,對其性能十分重要,必須足夠大,可是過大時,使得Innodb 關閉時候須要更多時間把髒頁從緩衝池中刷新到磁盤中;
總內存-(每一個線程所須要的內存*鏈接數)-系統保留內存
key_buffer_size,定義了MyISAM所使用的緩存池的大小,因爲數據是依賴存儲操做系統緩存的,因此要爲操做系統預留更大的內存空間;
select sum(index_length) from information_schema.talbes where engine='myisam'
注意:即便開發使用的表所有是Innodb表,也要爲MyISAM預留內存,由於MySQL系統使用的表仍然是MyISAM表。
max_connections控制容許的最大鏈接數,通常2000更大。不要使用外鍵約束保證數據的完整性。
八、性能優化順序
從上到下:
3、數據庫結構優化
一、數據庫結構優化目的
二、數據庫結構設計步驟
三、數據庫範式設計與反範式化
可參考「數據庫邏輯設計之三大範式通俗理解,一看就懂,書上說的太晦澀」
四、物理設計
可參考「MySQL中字段類型與合理的選擇字段類型;int(11)最大長度是多少?,varchar最大長度是多少」
4、高可用架構設計
一、讀寫分離
5、數據庫索引優化
一、兩種主要數據結構:B-tree和Hash
1)B-tree結構
B-tree索引的限制:
2)Hash結構
Hash索引的限制:
3)MySQL常見索引和各類索引區別
PRIMARY KEY(主鍵索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
UNIQUE(惟一索引) ALTER TABLE `table_name` ADD UNIQUE (`column`)
INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
組合索引 ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
二、使用索引好處和索引缺陷
1)爲何要使用索引
2)索引不是越多越好
索引就比如一本書的目錄,它會讓你更快的找到內容,顯然目錄(索引)並非越多越好,假如這本書1000頁,而有500頁是目錄,它固然效率低,目錄是要佔紙張的,而索引是要佔磁盤空間的。
三、索引優化策略
1)索引列上不能使用表達式和函數
2)前綴索引和索引列的選擇性
Innodb索引列最大寬度爲667個字節(utf-8 差很少255個字符),MyIsam索引類寬度最大爲1000個字節,因而出現前綴索引,索引的選擇性。
對於列的值較長,好比BLOB、TEXT、VARCHAR,就必須創建前綴索引,即將值的前一部分做爲索引。這樣既能夠節約空間,又能夠提升查詢效率。但沒法使用前綴索引作 ORDER BY 和 GROUP BY,也沒法使用前綴索引作覆蓋掃描。
語法: ALTER TABLE table_name ADD KEY(column_name(prefix_length))
如何選擇索引列的順序:
3)組合/聯合索引策略
若是索引了多列,要遵照最左前綴法則。指的是查詢從索引的最左前列開始而且不跳過索引中的列。
4)覆蓋索引策略
跟組合索引有點相似,若是索引包含全部知足查詢須要的數據的索引則成爲覆蓋索引(Covering Index),也就是平時所說的不須要回表操做。即索引的葉子節點上面包含了他們索引的數據(hash索引不能夠)。
判斷標準:使用explain,能夠經過輸出的extra列來判斷,對於一個索引覆蓋查詢,顯示爲using index,MySQL查詢優化器在執行查詢前會決定是否有索引覆蓋查詢。
優勢:
沒法使用覆蓋索引的狀況:
5)SQL索引優化總結口訣(套路重點)
全值匹配我最愛,最左前綴要遵照;
帶頭大哥不能死,中間兄弟不能斷;
索引列上不計算,範圍以後全失效;
LIKE百分寫最右,覆蓋索引不寫 *;
不等空值還有or,索引失效要少用;
字符單引不可丟,SQL高級也不難 ;
四、使用索引來優化查詢
1)利用索引排序
五、索引的維護和優化
1)刪除重複索引
注:主鍵約束至關於(惟一約束 + 非空約束)
一張表中最多有一個主鍵約束,若是設置多個主鍵,就會出現以下提示:Multiple primary key defined!!!
2)刪除冗餘索引
檢查工具:pt-duplicate-key-checker
6、SQL查詢優化
一、獲取有性能問題SQL的三種方式
1)慢查日誌分析工具
相關配置參數:
slow_query_log # 啓動中止記錄慢查日誌,慢查詢日誌默認是沒有開啓的能夠在配置文件中開啓(on)
slow_query_log_file # 指定慢查日誌的存儲路徑及文件,日誌存儲和數據從存儲應該分開存儲
long_query_time # 指定記錄慢查詢日誌SQL執行時間的閥值默認值爲10秒一般,對於一個繁忙的系統來講,改成0.001秒(1毫秒)比較合適
log_queries_not_using_indexes #是否記錄未使用索引的SQL
經常使用工具:mysqldumpslow和pt-query-digest
pt-query-digest --explain h=127.0.0.1,u=root,p=p@ssWord slow-mysql.log
2)實時獲取有性能問題的SQL(推薦)
SELECT id,user,host,DB,command,time,state,info
FROM information_schema.processlist
WHERE TIME>=60
查詢當前服務器執行超過60s的SQL,能夠經過腳本週期性的來執行這條SQL,就能查出有問題的SQL。
二、SQL的解析預處理及生成執行計劃
1)查詢過程描述
經過上圖能夠清晰的瞭解到MySQL查詢執行的大體過程:
2)查詢緩存對性能的影響(建議關閉緩存)
第一階段:
相關配置參數:
query_cache_type # 設置查詢緩存是否可用
query_cache_size # 設置查詢緩存的內存大小
query_cache_limit # 設置查詢緩存可用的存儲最大值(加上sql_no_cache能夠提升效率)
query_cache_wlock_invalidate # 設置數據表被鎖後是否返回緩存中的數據
query_cache_min_res_unit # 設置查詢緩存分配的內存塊的最小單
緩存查找是利用對大小寫敏感的哈希查找來實現的,Hash查找只能進行全值查找(sql徹底一致),若是緩存命中,檢查用戶權限,若是權限容許,直接返回,查詢不被解析,也不會生成查詢計劃。
在一個讀寫比較頻繁的系統中,建議關閉緩存,由於緩存更新會加鎖。將query_cache_type設置爲off,query_cache_size設置爲0。
3)第二階段:MySQL依照執行計劃和存儲引擎進行交互
這個階段包括了多個子過程:
一條查詢能夠有多種查詢方式,查詢優化器會對每一種查詢方式的(存儲引擎)統計信息進行比較,找到成本最低的查詢方式,這也就是索引不能太多的緣由。
三、會形成MySQL生成錯誤的執行計劃的緣由
四、MySQL優化器可優化的SQL類型
查詢優化器:對查詢進行優化並查詢MySQL認爲的成本最低的執行計劃。爲了生成最優的執行計劃,查詢優化器會對一些查詢進行改寫。
能夠優化的SQL類型:
五、查詢處理各個階段所須要的時間
1)使用profile(目前已經不推薦使用了)
set profiling = 1; #啓動profile,這是一個session級的配製執行查詢
show profiles; # 查詢每個查詢所消耗的總時間的信息
show profiles for query N; # 查詢的每一個階段所消耗的時間
2)performance_schema是5.5引入的一個性能分析引擎(5.5版本時期開銷比較大)
啓動監控和歷史記錄表:use performance_schema
update setup_instruments set enabled='YES',TIME = 'YES' WHERE NAME LIKE 'stage%';
update set_consumbers set enabled='YES',TIME = 'YES' WHERE NAME LIKE 'event%';
六、特定SQL的查詢優化
1)大表的數據修改
2)大表的結構修改
利用主從複製,先對從服務器進入修改,而後主從切換。
添加一個新表(修改後的結構),老表數據導入新表,老表創建觸發器,修改數據同步到新表,老表加一個排它鎖(重命名),新表重命名,刪除老表。
修改語句這個樣子:
alter table sbtest4 modify c varchar(150) not null default ''
利用工具修改:
3)優化not in 和 <> 查詢
子查詢改寫爲關聯查詢:
7、分庫分表
一、分庫分表的幾種方式
分擔讀負載 可經過 一主多從,升級硬件來解決。
1)把一個實例中的多個數據庫拆分到不一樣實例(集羣)
拆分簡單,不容許跨庫。但並不能減小寫負載。
2)把一個庫中的表分離到不一樣的數據庫中
該方式只能在必定時間內減小寫壓力。
以上兩種方式只能暫時解決讀寫性能問題。
3)數據庫分片
對一個庫中的相關表進行水平拆分到不一樣實例的數據庫中:
如何選擇分區鍵
分片中如何生成全局惟一ID
歡迎工做一到五年的Java工程師朋友們加入Java程序員開發: 854393687
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!