MySQL/MariaDB基礎第二次

1
MariaDB查詢緩存
緩存中的數據是開源形式的,以鍵值對(k/v)的形式存在
key:查詢語句的hash值;
value:查詢語句的查詢結果;
緩存中的數據主要是經過整個查詢語句的hash值的比較,徹底相同則命中;這樣經過緩存響應客戶端請求,能夠提升檢索效率;固然,也不是全部的查詢數據均可以緩存,那麼哪些數據不可以緩存呢?mysql

1.要查詢的數據庫中可能包含敏感信息;如MySQL數據庫中的各系統表;
2.在查詢語句中包含有用戶自定義的函數(UDF)
3.存儲函數;
4.用戶自定義變量;
5.對於臨時表發起的查詢請求;
6.包含列級別受權的查詢;
7.有着不肯定結果值的mysql的內鍵函數;如:NOW(),CURRENT_DATE(),CURRENT_TIME(),CURRENT_USER(),...
與查詢緩存相關的服務器參數:算法

MariaDB [hellodb]> show global variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_strip_comments | OFF |
| query_cache_type | ON |
| query_cache_wlock_invalidate| OFF |
+------------------------------+---------+
query_cache_limit:可以緩存查詢結果的最大字節數上限;(單語句結果集的上限)
在使用SELECT查詢語句時,應儘可能避免"SELECT *"查詢方式的應用,同時須要WHERE子句或HAVING子句對查詢結果進行優化處理;以使得查詢結果儘量精確;
對於哪些有着較大的查詢結果集的語句,應該在SELECT中明確顯式的使用SQL_NO_CACHE參數,以免查詢結果先如緩存再移除緩存;sql

query_cache_min_res_unit:查詢緩存中,內存塊的最小分配單元;能夠比較有效的避免內存碎片;
較大的變量值可能會帶來內存空間浪費;
較小的變量值會減小內存空間浪費,但會致使更加頻繁的內存分配和回收操做;長期下來必然產生內存碎片;數據庫

query_cache_size:查詢緩存申請的在內存中的總可用空間;
單位是字節,設定的值必須是1024的整數倍;緩存

query_cache_strip_comments:用於控制是否去掉SQL查詢語句中的註釋部分以後再做爲key部分存入查詢緩存;
默認值是"OFF",若是啓用,插入查詢緩存中的查詢語句是不帶有註釋部分信息的服務器

query_cache_type:緩存功能開啓與否的開關;
ON:啓用;僅不緩存"SQL_NO_CACHE"參數的查詢結果;
OFF:停用緩存;
DEMAND:按需緩存;默認不緩存,僅緩存"SQL_CACHE"參數的查詢結果;數據結構

query_cache_wlock_invalidate:若是某個鏈接會話對某表施加了寫鎖,是否依然能夠從緩存中查詢並返回查詢結果;
默認值爲"OFF",表示能夠;
ON,表示不能夠;
1
與查詢緩存相關的服務器參數:
image.png
Qcache_free_blocks:表示查詢緩存中目前還剩餘多少個blocks;若是該值顯示較大,則說明查詢緩存中內存碎片過多;ide

Qcache_free_memory:查詢緩存中還空閒的內存空間;
經過此狀態參數能夠評估當前系統中的查詢緩存的使用狀況;
若是剩餘量過小,且剩餘塊不少,大量的內存空間均以碎片形式存在;
若是剩餘量過小,且剩餘塊很少,分配的查詢緩存的內存空間恰好或略有欠缺;
若是剩餘量較大,分配的查詢緩存的內存空間太多,應進行相應調整;一旦調整了緩存大小,則其中存放的查詢結果會當即清除;函數

Qcache_hits:表示查詢緩存中查詢語句的命中次數;數字越大緩存效果越理想;性能

Qcache_inserts:表示未命中的然後通過處理將查詢結果添加至查詢請求的數量;
數值越大,則證實查詢緩存效果越不理想;
能夠經過規範書寫查詢請求的SQL語句減小此類查詢請求的數量;

注意:若是查詢緩存中確實沒有對應查詢語句的查詢緩存,此數值的增長也是正常現象;

Qcache_lowmem_prunes:該參數記錄了有多少條查詢請求是由於內存空間不足而基於LRU算法被移除緩存的;若是該數值過大,則表示分配的內存空間過小;

Qcache_not_cached:取決於query_cache_type變量的設置的做用下,沒有被緩存的查詢請求的數量;

Qcache_queries_in_cache:當前查詢緩存中緩存的查詢請求的結果的數量;

Qcache_total_blocks:當前查詢緩存中總計分配了多少個block;

查詢緩存命中率的計算:Qcache_hits/( Qcache_hits + Qcache_inserts )

注意:若是對錶進行了寫操做,例如增刪改等操做,則MySQL會自動將查詢緩存中與該表相關的緩存項所有清除;所以與此表有關的查詢請求必須從新構建緩存內容;

1.儘量批量寫入(構建自定義過程;啓用事務),儘可能減小屢次的單寫入操做;
2.緩存空間不宜設置過大,若是大量緩存同時失效,會使得MySQL的執行引擎壓力劇增,可能會致使服務器假死;
3.必要時,須要使用SQL_CACHE和SQL_NO_CACHE等SELECT語句中的參數來手動控制緩存存入與否;
4.對於密集型寫操做應用場景來講,禁用緩存功能可能提高服務器性能;
接下來作個實例:
1.首先要保證query_cache_type開啓:
image.png
2.爲緩存空間設置一個大小
image.png
image.png
image.png
3.查詢一下某個數據的數據表;
image.png
//在狀態參數中未命中出現一次,由於沒有緩存;而且此次查詢完成後,緩存了一條信息;
image.png
4.再次進行與上次查詢同樣的查詢;
//此次hits段命中了一次;你能夠屢次查詢查看命中次數;
image.png
image.png
1
MySQL的索引
那麼是爲了什麼而提出的索引呢,即索引的做用是什麼呢:當MySQL中數據過多時,要求檢索的速度也應該高,因此,爲了提升檢索速度,提出了索引這一律念;什麼是索引:也就是指定的表中的數據子集;即:將表中某個或某些字段中的數據提取出來,另存爲用一個特定數據結構進行組織的數據。
索引有不一樣類型:FULLTEXT,SPACIAL,B+ TREE,HASH;因爲存儲引擎不一樣,支持的索引的類型也不一樣:
1
2
InnoDB存儲引擎支持:B+ TREE,HASH;
MEMORY存儲引擎:顯示的支持HASH索引;

1.全鍵值匹配:精確匹配某個值;
select ... where Name='Xu Wenlong'
2.左前綴匹配:值精確到數據起始位置的一部分:
select ... where Name like 'G%'
3.區間數據的連續數值匹配,一般用於BETWEEN...AND...環境中:
select ... where age between 30 and 50;
4.區間數據的離散值匹配;一般用於IN列表環境或OR列表環境;也是精確值匹配;
select ... where StuID IN (1,3,7)
5.精確匹配左列,範圍匹配右側其餘列;
select ... where StuID > 10 and name like 'a%';
6.對於覆蓋索引的查詢請求:

1.若是查詢條件不是精確從最左側列開始的,索引無效;
對StuID字段作索引,select ... where Name like 'A%' and StuID>10;
2.若是索引了多列,若跳過索引中的某列,索引無效:
對StuID,Name,Age作索引,select ... where StuID>10 and Age>20;
3.若是索引了多列,且在查詢語句中對某個列作範圍匹配,則其右側列不能再使用索引優化查詢;
對StuID,Name,Age作索引,select ... where StuID>10 and Name like 'a%';
1
HASH索引:基於HASH表實現的索引;很是適用於值的精確匹配的查詢請求;
適用的場景:只支持等值比較查詢:如:=,IN(),<=>(NULL safe equal());
不適用場景:全部的非精確值的比較查詢:

索引的優勢:
1.較少須要掃描的數據總量,減小IO次數;
2.腳面對掃描的數據進行再次排序;
3.避免生成和使用臨時表;
4.將隨機IO轉換成順序IO;
定義索引的通常性規則:
1.選擇用於索引的數據類型;
越小的數據類型越適於作索引;
越簡單的數據類型越適於作索引;
儘可能避免該字段中出現"NULL"值;若是必需要使用空值;建議使用"0"或一個空的字符串或者某個承認的特殊值來代替"NULL"值;
2.選擇主鍵的類型;
優先選擇整型;
×××數據能夠更快速被處理;並且可使用AUTO_INCREMENT修飾符避免重複數據;
儘可能避免使用字符型;
存儲字符型數據須要消耗更多的空間,處理字符型數據須要消耗更多的CPU和內存資源,處理速度較慢;
高性能索引的定義策略:
1.在WHERE子句中以獨立使用某列作判斷條件爲最佳,儘可能避免該列直接參數運算;
select ... where Age+2>10;
2.最左前綴索引:索引應該構建於字段的最左側的一個或連續的多個字符;具體的選擇數量能夠經過"索引選擇性"進行評估;
索引選擇性:不重複的索引值和數據表的記錄總數的比值;
3.多列索引的選擇;
WHERE條件子句中使用AND運算符鏈接多個查詢條件;儘可能避免使用OR運算符;
若是使用OR運算符,應該基於每一個列作單列索引;
4.選擇合適的索引定義次序;選擇性最高的列放在最左側;

EXPLAIN語句
對索引進行分析,查看索引的應用信息;
用法:
EXPLAIN [explain_type] SELECT select_options

explain_type: EXTENDED | PARTITIONS
EXTENDED:顯示擴展信息;
PARTITIONS:用於分區表;
下面來上一個例子:
image.png
我們對個字段來作個解釋:
id:當前的查詢語句中,各個SELECT語句的編號;

select_type:查詢類型;
1
簡單查詢:SIMPLE //即經過交叉鏈接來查詢;
image.png
1
複雜查詢:
簡單子查詢(用於WHERE子句中的子查詢):SUBQUERY
image.png

用於FROM語句中的子查詢;DERIVED
image.png

聯合查詢中的第一個查詢:PRIMARY
聯合查詢中其餘的查詢:UNION
image.png
聯合查詢時生成的臨時表查詢:UNION RESULT
image.png
table:當前的查詢語句所針對的表;
type:關聯類型,或稱爲訪問類型;也能夠理解爲MySQL是如何查詢表中的行;
ALL:全表掃描;,MySQL將遍歷全表以找到能夠匹配的行;
index:全表掃描,與ALL所不一樣的是index類型只是遍歷索引樹;
range:索引範圍掃描,對索引的掃描從某一個點開始,返回匹配某一個值域的行;
一般能夠基於指定的索引,WHERE子句使用IN列表、BETWEEN...AND...、或帶有"=",">","<"等的查詢;
ref:使用非惟一索引掃描或者使用惟一索引的左前綴掃描;返回匹配某個單獨值的行;
eq_ref:相似於ref,區別就是使用惟一索引,對於每個索引鍵值,表中都只有一條記錄匹配;不管是單表查詢仍是多表查詢,都使用主鍵或惟一鍵索引來做爲關聯條件;
const,system:當MySQL對查詢部分進行優化,而且將優化結果轉換爲一個常量,使用const類型;
system類型是一個const類型特例,當要查詢的表中只有一行時,使用system類型;
NULL:MySQL在優化過程當中分解查詢語句,而執行時不用訪問表或索引;
image.png
image.png
image.png
image.png
image.png
possible_keys:爲了執行查詢語句,MySQL可能使用哪一個索引在表中查找到記錄;
若是查詢所涉及到的字段上存在索引,則該索引會被列出,但不必定會被查詢使用;
key:顯示MySQL數據庫在查詢過程當中,實際使用到的索引;若是查詢過程沒有用到任何索引,則此處顯示爲"NULL";
key_len:表示索引中能夠被引用的字節數;能夠經過該列計算查詢中使用的索引的長度;
注意:key_len顯示的值一般爲索引字段的最大可能長度,並非實際的使用長度;所以key_len是根據表定義時指定的字段長度計算獲得的,而並非在表中經過檢索數據獲得的;
ref:在利用key字段所顯示的索引完成查詢操做時所引用的列或常量值;若是都沒有則顯示爲"NULL";
rows:表示MySQL根據表統計信息及索引選用的狀況,估算的本次檢索所須要去查找到的全部記錄的過程當中須要讀取的表的行數;
Extra:額外信息,或稱擴展信息;
Using where:表示MySQL服務器將在存儲引擎檢索後再次進行調校過濾;許多的where條件裏涉及到索引中的列而且當MySQL讀取該索引時,既能夠被存儲引擎檢驗;
Using index:使用了覆蓋索引進行檢索;
Using temporary:在查詢過程當中使用了臨時表來存放查詢結果集;常見於排序或分組查詢;
Using filesort:MySQL中沒法利用索引完成排序操做就稱爲"文件排序";
Using join buffer:強調了在獲取鏈接條件時沒有使用到索引,而且須要鏈接緩衝區來存儲中間結果。若是出現了該值,須要根據查詢的具體狀況適當的添加索引以提示查詢性能;
Impossible where:若是該值出現,則意味着where子句沒有發現符合條件的行;
Select tables optimized away:該值意味着僅經過使用索引來進行查詢,可是優化器可能從聚合函數的結果中給出一個可行的優化方案;
Using sort-union(...)
Using union(...)
Using intersect(...)
上述狀況多出現於在實現查詢的過程當中,決定使用不止一個索引時;
filtered:從可選的行中再次過濾以後選擇出最終的查詢結果的比值;
image.png
image.png
image.png

EXPLAIN總結:1.EXPLAIN語句並不會告知關於觸發器、存儲過程相關的信息或用戶自定義函數對查詢的影響狀況;2.EXPLAIN語句不會考慮任何Cache;3.EXPLAIN語句不會顯示MySQL自身的執行查詢時所做出的優化操做;4.部分統計信息並非精確值,而是估算結果;5.EXPLAIN語句只能分析解釋SELECT語句,其餘的暗含SELECT語句的操做;其餘的非SELECT操做只有在重寫爲SELECT後,才能查看執行計劃

相關文章
相關標籤/搜索