MariaDB數據庫存儲引擎、索引和EXPLAIN

                      MariaDB數據庫存儲引擎、索引和EXPLAINhtml

----------------------------------------------------------------------------------------------------------------------------------------mysql

一、存儲引擎sql

MySQL5.5.5前默認的數據庫引擎爲MyISAM,以後的是InnoDB,如今新版本是InnoDB的增強版XtraDB數據庫

(1)MyIsam與InnoDB的區別緩存


MyISAM安全

InnoDB性能優化

最大存儲服務器

256TBsession

64TB併發

事務

N

Y

表鎖

行鎖

MVCC

N

Y

B-TREE

Y

Y

全文索引

N

Y

聚簇索引

N

Y

數據緩存

N

Y

索引緩存

Y

Y

解釋:

    <1>事務:多種操做的集合。多會話訪問數據庫時,每個操做都會有一個ID,之間互不干擾。假設A在數據庫的某張表中有先插入、再刪除的操做,操做同時B在查詢這張表,那麼B查詢到的結果是A插入未刪時的數據仍是A已經刪除的操做?其實當A作插入insert操做時,數據庫會自動給該動做分配一個ID,作刪除的操做時候回再分配一個ID,且後面操做的ID大於簽名操做的ID。若是B的查詢操做ID位於A的插入以後,刪除以前,那麼B查詢到的就是A在insert後的結果,delete以前的結果

Ainsert=10,Adelete=20,Bselect=15,此時B能夠查到A在insert的結果,查詢不到A的delete後的結果。

    <2>鎖:表鎖:鎖的動做是對整個表上鎖,上鎖後其餘用戶不得訪問讀寫

    行鎖:鎖的動做是針對某一行上鎖

    <3>髒數據:事務過程當中尚未結束完的數據,好比說剛纔說的A在insert和delete之間未完成的數據

    <4>MVCC:多版本併發控制機制

(2)存儲引擎特定

<1>MyISAM特色:

不支持事務

表級鎖定

讀寫相互阻塞,寫入不能讀,讀時不能寫

只緩存索引

不支持外鍵約束

不支持聚簇索引

讀取數據較快,佔用資源較少

不支持MVCC(多版本併發控制機制)高併發

崩潰恢復性較差

MySQL5.5.5前默認的數據庫引擎

<2>適用場景:只讀(或者寫較少)、表較小(能夠接受長時間進行修復操做)

<3>MyISAM引擎文件:

tbl_name.frm: 表格式定義

tbl_name.MYD: 數據文件

tbl_name.MYI: 索引文件

<4>InnoDb引擎特色

行級鎖

支持事務,適合處理大量短時間事務

讀寫阻塞與事務隔離級別相關

可緩存數據和索引

支持聚簇索引

崩潰恢復性更好

支持MVCC高併發

從MySQL5.5後支持全文索引

從MySQL5.5.5開始爲默認的數據庫引擎

<5>InnoDB引擎下,建議修改/etc/my.cnf,在[mysqld]下添加defaults-storage-engine=INNODB和innodb-file-per-table,不然全部InnoDB表的數據和索引放置於同一個表空間中image.png

設置好後今後以後新建的數據庫都將數據文件和表格式定義分開存放

數據文件(存儲數據和索引):tb_name.ibd,表格式定義:tb_name.frm

二、其它存儲引擎

(1)Performance_Schema:Performance_Schema數據庫

(2)Memory :將全部數據存儲在RAM中,以便在須要快速查找參考和其餘相似數據的環境中進行快速訪問。適用存放臨時數據。引擎之前被稱爲HEAP引擎

(3)MRG_MyISAM:使MySQL DBA或開發人員可以對一系列相同的MyISAM表進行邏輯分組,並將它們做爲一個對象引用。適用於VLDB(Very Large Data Base)環境,如數據倉庫

(4)Archive :爲存儲和檢索大量不多參考的存檔或安全審覈信息,只支持SELECT和INSERT操做;支持行級鎖和專用緩存區

(5)Federated聯合:用於訪問其它遠程MySQL服務器一個代理,它經過建立一個到遠程MySQL服務器的客戶端鏈接,並將查詢傳輸到遠程服務器執行,然後完成數據存取,提供連接單獨MySQL服務器的能力,以便從多個物理服務器建立一個邏輯數據庫。很是適合分佈式或數據集市環境

(6)BDB:可替代InnoDB的事務引擎,支持COMMIT、ROLLBACK和其餘事務特性

(7)Cluster/NDB:MySQL的簇式數據庫引擎,尤爲適合於具備高性能查找要求的應用程序,這類查找需求還要求具備最高的正常工做時間和可用性

(8)CSV:CSV存儲引擎使用逗號分隔值格式將數據存儲在文本文件中。可使用CSV引擎以CSV格式導入和導出其餘軟件和應用程序之間的數據交換

(9)BLACKHOLE :黑洞存儲引擎接受但不存儲數據,檢索老是返回一個空集。該功能可用於分佈式數據庫設計,數據自動複製,但不是本地存儲

(10)example:「stub」引擎,它什麼都不作。可使用此引擎建立表,但不能將數據存儲在其中或從中檢索。目的是做爲例子來講明如何開始編寫新的存儲引擎

三、MariaDB支持的其它存儲引擎:OQGraph、SphinxSE、TokuDB、Cassandra、CONNECT、SQUENCE

四、管理存儲引擎

(1)查看庫中全部表使用的存儲引擎

    Show table status from db_name;

(2)查看庫中指定表的存儲引擎

    show table status like ' tb_name';

    show create table tb_name;

(3)設置表的存儲引擎:

    CREATE TABLE tb_name(... ) ENGINE=InnoDB;

    ALTER TABLE tb_nameENGINE=InnoDB;

(4)查看引擎

    SHOW ENGINES;

五、MySQL中的系統數據庫

(1)mysql數據庫:mysql的核心數據庫,相似於sql server中負責存儲數據庫的用戶、權限設置、關鍵字等mysql本身須要使用的控制和管理信息

(2)performance_schema:mysql 5.5開始新怎的數據庫,主要用於收集數據庫服務器性能參數,庫裏表的存儲引擎均爲performance_schema,用戶不能建立存儲引擎爲performance_schema的表

(3)information_schema數據庫:mysql 5.0以後產生的,一個虛擬數據庫,物理上並不存在。提供了訪問數據庫元數據的方式,即數據的數據。

六、服務器配置

(1)mysqld選項,服務器系統變量和服務器狀態變量,在兩個官方網址中查詢是服務器變量仍是服務器選項

    https://dev.mysql.com/doc/refman/5.7/en/mysqld-option-tables.html

    https://mariadb.com/kb/en/library/full-list-of-mariadb-options-system-and-status-variables/

(2)服務器系統變量:分全局和會話兩種

(3)服務器狀態變量:分全局和會話兩種

(4)獲取運行中的mysql進程使用各服務器參數及其值

進入數據庫輸入SQL語句

SHOW GLOBAL VARIABLES;

SHOW [SESSION] VARIABLES;image.png

      (5)設置服務器選項方法:

<1>在命令行中設置./mysqld_safe --skip-name-resolve=1;

<2>在配置文件my.cnf中添加skip_name_resolve=1,避免IP被反向解析爲名字,建議添加此項

(6)修改全局變量:僅對修改後新建立的會話有效;對已經創建的會話無效

    mysql> SET GLOBAL system_var_name=value;

    mysql> SET @@global.system_var_name=value;

(7)修改會話變量:

    mysql> SET [SESSION] system_var_name=value;

    mysql> SET @@[session.]system_var_name=value;

(8)狀態變量(只讀):用於保存mysqld運行中的統計數據的變量,不可更改

    mysql> SHOW GLOBAL STATUS;

    mysql> SHOW [SESSION] STATUS;

注意:

(1)有些既是服務器變量,又是服務器選項,好比說--binlog-cacho-size爲選項,但也有binlog_cache_size的變量

(2)當修改變量時用SET [GLOBAL] VARNAME=value做爲修改,用show variables like ' ';查詢,該變量修改後會在重啓後消失,並且變量不支持加入配置文件中。選項的修改能夠直接將該選項放入/etc/my.cnf下的[mysqld],該修改成永久保存。查找是服務器變量仍是服務器選項去剛給的官網網址能夠查找

(3)查詢變量show [global] variables like '...%';

    查詢狀態變量show [global] status like '...%';,不可更改,只讀

七、服務器變量SQL_MODE

(1)SQL_MODE:對其設置能夠完成一些約束檢查的工做,可分別進行全局的設置或者當前會話的設置

(2)開啓方式:SET SQL_MODE='traditional',加上global對全局設置,不加global對當前會話設置

(3)常見MODE

<1>NO_AUTO_CREATE_USER:禁止GRANT建立密碼爲空的用戶

<2>NO_ZERO_DATE:在嚴格模式,不容許使用‘0000-00-00’的時間

<3>ONLY_FULL_GROUP_BY:對於GROUP BY分組操做,若是SELECT的字段沒有在分組GROUP BY中存在會認爲這個SQL語句是不合法的

<4>NO_BACKSLASH_ESCAPES:反斜槓\做爲普通字符而非轉義字符

<5>PIPES_AS_CONCAT:將||視爲鏈接操做符而非「或運算符」

八、查詢緩存

(1)查詢先看是否有查詢緩存,若是有將直接顯示緩存,加快了速度。因爲查詢緩存運用了哈希運算,所以若是想要引用查詢緩存,SQL語句使用須要與在查詢緩存中的SQL語句如出一轍,甚至大小寫一致

(2)哪些查詢可能不會被緩存

<1>查詢語句中加了SQL_NO_CACHE參數

<2>查詢語句中含有得到值的函數,包含自定義函數,如:NOW()

CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ()等

<3>對系統數據庫的查詢:mysql、information_schema查詢語句中使用SESSION級別變量或存儲過程當中的局部變量

<4>查詢語句中使用了LOCK IN SHARE MODE、FOR UPDATE的語句,查詢語句中相似SELECT …INTO 導出數據的語句

<5>對臨時表的查詢操做;存在警告信息的查詢語句;不涉及任何表或視圖的查詢語句;某用戶只有列級別權限的查詢語句

<6>事務隔離級別爲Serializable時,全部查詢語句都不能緩存

(3)查詢服務器相關變量

show variables like 'query_cache%';image.png

<1>query_cache_min_res_unit: 查詢緩存中內存塊的最小分配單位,默認4k,較小值會減小浪費,但會致使更頻繁的內存分配操做,較大值會帶來浪費,會致使碎片過多,內存不足

<2>query_cache_limit:單個查詢結果能緩存的最大值,默認爲1M,對於查詢結果過大而沒法緩存的語句,建議使用SQL_NO_CACHE

<3>query_cache_size:查詢緩存總共可用的內存空間;單位字節,必須是1024的整數倍,最小值40KB,低於此值有警報

<4>query_cache_wlock_invalidate:若是某表被其它的會話鎖定,是否仍然能夠從查詢緩存中返回結果,默認值爲OFF,表示能夠在表被其它會話鎖定的場景中繼續從緩存返回數據;ON則表示不容許

<5>query_cache_type: 是否開啓緩存功能,取值爲ON, OFF, DEMAND,當query_cache_type的值爲ON或1時,查詢緩存功能打開,SELECT的結果符合緩存條件即會緩存,顯式指定SQL_NO_CACHE,不予緩存,此爲默認值;當query_cache_type的值爲DEMAND或2時,查詢緩存功能按需進行,顯式指定SQL_CACHE的SELECT語句纔會緩存;其它均不予緩存

注意:以上爲服務器變量,設置時候是SET [GLOBAL] VARNAME=value;

    查詢變量或者選項示例:

image.png


九、優化查詢緩存

image.png

十、查詢緩存

查詢緩存相關的狀態變量:SHOW GLOBAL STATUS LIKE ‘Qcache%';

(1)Qcache_free_blocks:處於空閒狀態Query Cache中內存Block 數

(2)Qcache_total_blocks:Query Cache 中總Block ,當Qcache_free_blocks相對此值較大時,可能用內存碎片,執行FLUSH QUERY CACHE清理碎片

(3)Qcache_free_memory:處於空閒狀態的Query Cache 內存總量

(4)Qcache_hits:Query Cache 命中次數,好比輸入同一個SQL查詢語句兩次,該記錄會加1,兩次輸入的SQL語句大小必須一致

(5)Qcache_inserts:向Query Cache 中插入新的Query Cache 的次數,即沒有命中的次數

(6)Qcache_lowmem_prunes:0記錄有多少條查詢由於內存不足而被移除出查詢緩存

(7)Qcache_not_cached:沒有被Cache 的SQL 數,包括沒法被Cache 的SQL 以及因爲query_cache_type設置的不會被Cache 的SQL語句,好比select now()輸入後,該記錄會加1

(8)Qcache_queries_in_cache:在Query Cache 中的SQL 數量image.png

由此能夠得出命中率和內存使用率估算:

(1)查詢緩存中內存塊的最小分配單位query_cache_min_res_unit:(query_cache_size-Qcache_free_memory) / Qcache_queries_in_cache

(2)查詢緩存命中率:Qcache_hits/ ( Qcache_hits+ Qcache_inserts) * 100%

(3)查詢緩存內存使用率:(query_cache_size–qcache_free_memory) / query_cache_size* 100%

十一、InnoDB存儲引擎

(1)InnoDB存儲引擎的緩衝池:一般InnoDB存儲引擎緩衝池的命中不該該小於99%

(2)查看相關狀態變量:只讀

show global status like 'innodb%read%'\G

<1>Innodb_buffer_pool_reads: 表示從物理磁盤讀取頁的次數

<2>Innodb_buffer_pool_read_ahead: 預讀的次數

<3>Innodb_buffer_pool_read_ahead_evicted: 預讀頁,可是沒有讀取就從緩衝池中被替換的頁數量,通常用來判斷預讀的效率

<4>Innodb_buffer_pool_read_requests: 從緩衝池中讀取頁次數

<5>Innodb_data_read: 總共讀入的字節數

<6>Innodb_data_reads: 發起讀取請求的次數,每次讀取可能須要讀取多個頁

十二、索引

(1)索引是特殊結構:定義在查找時做爲查找的字段

(2)索引實現基於存儲引擎

(3)優勢:

<1>索引能夠下降服務須要掃描的數據量,減小了IO次數

<2>索引能夠幫助服務器避免排序和使用臨時表

<3>索引能夠幫助將隨機IO轉爲順序IO

(4)缺點:

<1>佔用額外空間,影響插入速度,不過對於具備大量查詢需求的數據庫是值得的

<2>數據庫發生變化,索引也須要更新

(5)索引類型

<1>B-TREE(念做B樹)、B+ TREE、HASH、R TREE

<2>聚簇(集)索引、非聚簇索引:數據和索引是否存儲在一塊兒

彙集索引:數據和索引放在一塊兒,InnoDB

非彙集索引:數據和索引分離放置,MyISAM

<3>主鍵索引、二級(輔助)索引

主鍵索引:索引的排列次序和數據在磁盤上的排列次序是一致的

二級索引:利用惟一鍵創建索引

<4>稠密索引、稀疏索引:是否索引了每個數據項

稠密索引:索引存放了每一個數據項

稀疏索引:索引存放了部分數據項

<5>簡單索引、組合索引

左前綴索引:取前面的字符作索引

覆蓋索引:從索引中便可取出要查詢的數據,性能高

(6)B-TREE,平衡樹,balanced treeimage.png

(7)B+TREE,比B-TREE穩定image.png

<1>可使用B+Tree索引的查詢類型:

全值匹配:精確全部索引列,如:姓wang,名xiaochun,年齡30

匹配最左前綴:即只使用索引的第一列,如:姓wang

匹配列前綴:只匹配一列值開頭部分,如:姓以w開頭的

匹配範圍值:如:姓ma和姓wang之間

精確匹配某一列並範圍匹配另外一列:如:姓wang,名以x開頭的

只訪問索引的查詢

<2>B+Tree索引的限制:

如不從最左列開始,則沒法使用索引,如:查找名爲xiaochun,或姓爲g結尾

不能跳過索引中的列:如:查找姓wang,年齡30的,只能使用索引第一列

若是查詢中某個列是爲範圍查詢,那麼其右側的列都沒法再使用索引:如:姓wang,名x%,年齡30,只能利用姓和名上面的索引

<3>特別提示:

索引列的順序和查詢語句的寫法應相匹配,才能更好的利用索引

爲優化性能,可能須要針對相同的列但順序不一樣建立不一樣的索引來知足不一樣類型的查詢需求

(8)Hash索引

<1>Hash索引:基於哈希表實現,基於哈希表實現,只有精確匹配索引中的全部列的查詢纔有效,索引自身只存儲索引列對應的哈希值和數據指針,索引結構緊湊,查詢性能好

<2>Memory存儲引擎支持顯式hash索引,InnoDB和MyISAM存儲引擎不支持

<3>適用場景:只支持等值比較查詢,包括=, <=>, IN()

<4>不適合使用hash索引的場景

不適用於順序查詢:索引存儲順序的不是值的順序

不支持模糊匹配

不支持範圍查詢

不支持部分索引列匹配查找:如A,B列索引,只查詢A列索引無效

(9)地理空間索引( Geospatial indexing)

MyISAM支持地理空間索引,可使用任意維度組合查詢,使用特有的函數訪問,經常使用於作地理存儲存儲,使用很少

InnoDB從MySQL5.7後開始支持

(10)全文索引

在文本中查找關鍵詞,而不是直接比較索引中的值,相似搜索引擎

InnoDB從MySQL5.6後開始支持

(11)冗餘和重複索引:

冗餘索引:(A),(A,B),好比說有了idx_name_age創建的符合索引,此時再有name或者age的索引,name或者age就是冗餘索引

重複索引:已經有索引,再次創建索引

(12)索引優化策略:

<1>獨立地使用列:儘可能避免其參與運算,獨立的列指索引列不能是表達式的一部分,也不能是函數的參數,在where條件中,始終將索引列單獨放在比較符號的一側

<2>左前綴索引:構建指定索引字段的左側的字符數,要經過索引選擇性來評估,好比說某個表格name字段定義時候是CHAR(50),但name字段中的全部值按照CHAR(10)的規格就可使用,此時定義name索引時能夠更改name字段字符數,CREATE INDEX idx_name ON tbl_name(name(10));

索引選擇性:不重複的索引值和數據表的記錄總數的比值

<3>多列索引:AND操做時更適合使用多列索引,而非爲每一個列建立單獨的索引,查詢語句的where從句中用and鏈接兩個加了索引的字段

<4>選擇合適的索引列順序:無排序和分組時,將選擇性最高放左側 

1三、管理索引

(1)建立索引:

CREATE INDEX index_name ON tbl_name (index_col_name[(length)],...);

help CREATE INDEX;

(2)索引的使用:

SELECT ... WHERE 字符(加索引的字段) { like | in | = ...};

(3)刪除索引:

DROP INDEX index_name ON tbl_name;

(4)查看索引:

SHOW INDEXES FROM [db_name.]tbl_name;

(5)優化表空間:

OPTIMIZE TABLE tb_name;,當索引創建後長時間不用

(6)查看索引的使用

SET GLOBAL userstat=1;

SHOW INDEX_STATISTICS;

示例:現有一存儲過程,能夠實現創建99999個用戶id、name、age的表格image.png

以後mysql DB < FILE.sql,進入數據庫調用call protestlog,產生數據表如圖

image.png

共有99999條這樣的記錄,如今咱們開始示例索引image.png

利用索引查詢和不利用索引查詢image.png

刪除索引

image.png

創建複合索引

image.png

1四、索引優化建議

(1)只要列中含有NULL值,就最好不要在此例設置索引,複合索引若是有NULL值,此列在使用時也不會使用索引

(2)儘可能使用短索引,若是能夠,應該制定一個前綴長度

(3)對於常常在where子句使用的列,最好設置索引

(4)對於有多個列where或者order by子句,應該創建複合索引

(5)對於like語句,以%或者‘-’開頭的不會使用索引,以%結尾會使用索引,索引使用禁止使用like '%...'或者'%...%',只容許'...%'的形式

(6)儘可能不要在列上進行運算(函數操做和表達式操做)

(7)儘可能不要使用not in和<、>操做

1五、SQL語句性能優化

(1)查詢時,能不要*就不用*,儘可能寫全字段名

(2)大部分狀況鏈接效率遠大於子查詢

(3)多表鏈接時,儘可能小表驅動大表,即小表 join 大表

(4)在有大量記錄的表分頁時使用limit

(5)對於常用的查詢,能夠開啓緩存

(6)多使用explain和profile分析查詢語句

(7)查看慢查詢日誌,找出執行時間長的sql語句優化

1六、EXPLAIN

經過EXPLAIN來分析索引的有效性

(1)用法:EXPLAIN SELECT 從句

(2)id: 當前查詢語句中,每一個SELECT語句的編號

複雜類型的查詢有三種:

簡單子查詢

用於FROM中的子查詢

聯合查詢:UNION

注意:UNION查詢的分析結果會出現一個額外匿名臨時表

(3)select_type:

簡單查詢爲SIMPLE

複雜查詢:

SUBQUERY 簡單子查詢

PRIMARY 最外面的SELECT

DERIVED 用於FROM中的子查詢

UNION UNION語句的第一個以後的SELECT語句

UNION RESULT 匿名臨時表

(4)table:SELECT語句關聯到的表

(5)type:關聯類型或訪問類型,即MySQL決定的如何去查詢表中的行的方式,如下順序,性能從低到高

<1>ALL: 全表掃描

<2>index:根據索引的次序進行全表掃描;若是在Extra列出現「Using index」表示了使用覆蓋索引,而非全表掃描

<3>range:有範圍限制的根據索引實現範圍掃描;掃描位置始於索引中的某一點,結束於另外一點

<4>ref: 根據索引返回表中匹配某單個值的全部行

<5>eq_ref:僅返回一個行,但與須要額外與某個參考值作比較

<6>const, system: 直接返回單個行

(6)possible_keys:查詢可能會用到的索引

(7)key: 查詢中使用到的索引

(8)key_len: 在索引使用的字節數

(9)ref: 在利用key字段所表示的索引完成查詢時所用的列或某常量值

(10)rows:MySQL估計爲找全部的目標行而須要讀取的行數

(11)Extra:額外信息

Using index:MySQL將會使用覆蓋索引,以免訪問表

Using where:MySQL服務器將在存儲引擎檢索後,再進行一次過濾

Using temporary:MySQL對結果排序時會使用臨時表

Using filesort:對結果使用一個外部索引排序

示例

image.png

出現黃字狀況possible_keys有值,但key爲NULL

相關文章
相關標籤/搜索