架構、索引、鎖、語法、理論範式mysql
一、加快查詢數據速度(在數據以外,數據庫系統還維護着知足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就能夠在這些數據結構上實現高級查找算法。這種數據結構,就是索引。索引的出現就是爲了提升查詢效率,就像書的目錄。其實說白了,索引要解決的就是查詢問題。)算法
一、主鍵、惟一鍵和普通鍵等sql
主流索引是B+Tree 。此外還有hash結構和bitmap等,其中mysql不支持bitmap索引。數據庫
一、生成索引、創建二叉查找樹進行二分查找(平衡二叉樹、線性二叉樹、)數據結構
影響程序的數據速率和io還有關係,數據庫中二叉樹查找每個深度就會產生一次IO。架構
二、生成索引、創建B-Tree結構進行查找併發
→ 根節點至少包括兩個孩子。oracle
→ 樹中每一個節點最多含有m個孩子(m>=2)函數
→ 除根節點和葉節點外,其餘每一個節點至少有ceil(m/2)個孩子工具
Ceil:取上限
→ 全部葉子節點都位於同一層,葉子節點的高度相同
三、生成索引、創建B+-Tree結構進行查找(MySQL主要是經過此方式實現索引)
四、生成索引、創建Hash結構進行查找
B+樹是B樹的變體,其定定義基本與B樹相同,除了如下幾點
→ 非葉子節點的子樹指針與關鍵字個數相同
→ 非葉子節點的子樹指針P[i],指向關鍵字值[K[i],k[i+1]]的子樹
→ 非葉子節點僅用來索引,數據都保存在葉子節點中
→ 全部葉子節點均有一個鏈指針指向下一個葉子節點(方便作統計)
結論(B+ Tree更適合用來作存儲索引)
→ B+ 樹的磁盤讀寫代價更低(關鍵字都是存在節點中,節點中並不存放數據,這樣一次讀到內存中的關鍵字就比較多,io讀取次數也下降了)
→ B+ 樹的查詢效率更加穩定(內部節點並非最終指向文件內容的節點,只是指向葉子節點中關鍵字的索引,因此每一個查詢都是從根節點開始)
→ B+ 樹更有利於對數據庫的掃描(B+樹只要遍歷葉子節點就能夠對所有信息的掃描,範圍查詢之類的就比較方便)
缺點
→ 僅僅能知足「=」,「in」,不能使用範圍查詢
→ 沒法被用來避免數據的排序操做
→ 不能利用部分索引鍵查詢
→ 不能避免表掃描
→ 遇到大量Hash值相等的狀況後性能並不必定就會比B-Tree索引高
→ 密級索引文件中的每一個搜索碼值都對應一個索引值
→ 稀疏索引文件只爲索引碼的某些值創建索引項
InnoDB(mysql)
→ 若一個主鍵被定義,該主鍵則做爲密集索引
→ 若沒有主鍵被定義,該表的第一個惟一非空索引則做爲密級索引
→ 若不知足以上條件,innodb內部會生成一個隱藏主鍵(密集索引)
→ 非主鍵索引存儲相關鍵位和其餘對應用的主鍵值,包含兩次查找
MyIsAM中的數據和索引是分開存放在不一樣的文件中(.MYD,.MYI),innodb索引和數據是存放在一個文件中(.idb),都有一個.frm文件存放表結構。
一、根據慢日誌定位慢查詢sql
執行 show variables like ‘%query%’;
查看slow_query_log這個變量有沒有開啓,若沒有則須要開啓(set global sow_query_log = on),改變long_query_time的值,默認爲10s,改成1秒(set global sow_query_time = 1 )。
執行show status like ‘%slow_queries%’;
查看慢日誌中的慢查詢條數,而後在查詢語句前加上explain 進行分析
二、使用explain等工具分析sql
而後在查詢語句前加上explain 進行分析(結果中的兩個字段比較重要type,extra)。
三、修改sql或者儘可能讓sql走索引
給表中某個字段增長索引(alter table xxx add index idx_strName(strName))
一、最左前綴匹配原則,很是重要的原則,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配,比 a = 3 and b = 4 ,c > 5 and d = 6 ;若是創建(a、b、c、d)順序的索引,d是用不到索引的,若是創建(a、b、d、c)的索引則均可以用到,abd的順序能夠任意調整。
二、「=」和「in」能夠亂序,好比a = 3 and b = 4 ,c = 5創建(a,b,c)索引能夠任意順序,mysql的查詢優化器會幫你優化成索引能夠識別的形式。
數據量小的表不須要創建索引,創建會增長額外的索引開銷
數據變動須要維護索引,所以更多的索引意味着更多的維護成本
更多的索引意味着也須要更多的空間
MyISAM默認用的是表級鎖,不支持行級鎖
InnoDB默認用的是行級鎖,也支持表級鎖
lock tables xxx read|write;-- 給xxx表增長讀鎖
unlock tables;-- 釋放鎖
→ 頻繁執行全表count語句
→ 對數據進行增刪改的頻率不高,查詢很是頻繁
→ 沒有事物
→ 數據增刪改查都至關頻繁的
→ 可靠性要求比較高,要求支持事物
按所得粒度劃分
表級鎖、行級鎖、頁級鎖
按鎖級別劃分
共享鎖、排它鎖
按加鎖方式劃分
自動鎖、顯示鎖
按操做劃分
DML鎖(表中數據操做的)、DDL鎖(表結構發生變化的)
按使用方式劃分
樂觀鎖、悲觀鎖(排它鎖的鎖定便可實現)
原子性是指事務包含的全部操做要麼所有成功,要麼所有失敗回滾,所以事務的操做若是成功就必需要徹底應用到數據庫,若是操做失敗則不能對數據庫有任何影響。
一致性是指事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態,也就是說一個事務執行以前和執行以後都必須處於一致性狀態。
拿轉帳來講,假設用戶A和用戶B二者的錢加起來一共是5000,那麼無論A和B之間如何轉帳,轉幾回帳,事務結束後兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。
隔離性是當多個用戶併發訪問數據庫時,好比操做同一張表時,數據庫爲每個用戶開啓的事務,不能被其餘事務的操做所幹擾,多個併發事務之間要相互隔離。
即要達到這麼一種效果:對於任意兩個併發的事務T1和T2,在事務T1看來,T2要麼在T1開始以前就已經結束,要麼在T1結束以後纔開始,這樣每一個事務都感受不到有其餘事務在併發地執行。
事物隔離級別以及各級別下的併發訪問問題
→更新丟失 — mysql全部事物隔離級別在數據庫層面上都可避免
→髒讀 — read-committed 事物隔離級別以上可避免(髒讀是指在一個事務處理過程裏讀取了另外一個未提交的事務中的數據。)(oracle的默認隔離級別)
→不可重複讀 — repeatable-read事物隔離級別以上可避免(不可重複讀是指在對於數據庫中的某個數據,一個事務範圍內屢次查詢卻返回了不一樣的數據值,這是因爲在查詢間隔,被另外一個事務修改並提交了。)(mysql的默認隔離級別)
→幻讀 — Seriaizable事物隔離級別可避免(幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中全部的行的某個數據項作了從「1」修改成「2」的操做,這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值仍是爲「1」而且提交給數據庫。而操做事務T1的用戶若是再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺同樣,這就是發生了幻讀。)
事物隔離級別 |
跟新丟失 |
髒讀 |
不可重複讀 |
幻讀 |
未提交讀 |
× |
√ |
√ |
√ |
已提交讀 |
× |
× |
√ |
√ |
可重複讀 |
× |
× |
× |
√ |
串行化 |
× |
× |
× |
× |
持久性是指一個事務一旦被提交了,那麼對數據庫中的數據的改變就是永久性的,即使是在數據庫系統遇到故障的狀況下也不會丟失提交事務的操做。
一、Group by
a、知足「select 字句中的列名必須爲分組列或列函數」
b、列函數對於group by自居定義的每一個組各返回一個結果
二、Having
a、一般與group by 子句一塊兒使用
b、where過濾行,having過濾組
c、出如今同一sql的順序:where 》 group by 》 having
三、Count、sum、max、min、avg