ps:
一、緩存存放在一個相似HashMap的引用表中,hash值經過查詢自己、數據庫自己、客戶端協議版本號等生成
二、查詢中包含任何自定義函數、存儲函數、用戶變量、臨時表、系統表查詢結果都不會被緩存mysql
myisam和innerdb的主要區別 一、myisam只能支持表級鎖,innerdb支持行級鎖 二、myisam不支持事務,innerdb支持事務 三、myisam不支持外鍵,innerdb支持 四、myisam的索引的數據結構爲索引文件與數據文件分離,索引的葉子節點保存數據文件的指針 innerdb的表一定存在一個主鍵索引(彙集索引),若是有主鍵的話,以該主鍵建立索引,若沒有主鍵,選擇一個不爲空的惟一索引代替,若也沒有,會隱式建立一個6個字節的字段做爲主鍵建立彙集索引。sql
樂觀鎖:假設不會發生衝突,提早不上鎖,使用版本號,在提交時檢查版本號,若版本號發生變化,認爲數據失效,不去提交
悲觀鎖:假設會發生衝突,提早上鎖,例如共享鎖 排他鎖數據庫
共享鎖(讀鎖):其餘事務只能夠讀,不能夠寫
排他鎖(寫鎖):其餘事務既不能讀,也不能寫緩存
表鎖:當前表加鎖,顆粒度大,加鎖快,併發低,死鎖概率最高
頁鎖:當前頁加鎖,顆粒度通常,加鎖通常,併發通常,死鎖概率較高
行鎖:當前行加鎖,顆粒度小,加鎖慢,併發大,會出現死鎖較小服務器
死鎖:多個事務相互等待鎖的釋放,好比事務c1分別修改h1,h2兩行數據,c2分別修改h2,h1兩行數據,c1對h1添加排他鎖,c2對h2添加排他鎖,此時c1等待h2鎖的釋放,c2等待h1鎖的釋放,出現死鎖數據結構
SHOW STATUS LIKE 'Table%':查看錶鎖爭用狀況, 若Table_locks_waited 的值比較高,則說明存在着較嚴重的表級鎖爭用狀況併發
myisam在執行select操做時會自動給表加讀鎖,執行delete、update、insert自動給表加寫鎖,在自動加鎖的狀況下,myisam會一次性的得到當前事務所須要的所有鎖,因此不會出現死鎖的現象less
innerdb行級鎖是添加到索引項上的,只有經過索引條件檢索數據,InnoDB 才使用行級鎖,不然,InnoDB 將使用表鎖。函數
死鎖恢復:innerdb將持有最少行級排他鎖的事務進行回滾,只須要從新執行因死鎖回滾的事務便可 發生死鎖後,InnoDB 通常都能自動檢測到,並使一個事務釋放鎖並回退,另外一個事務得到鎖,繼續完成事務。但在涉及外部鎖,或涉及表鎖的狀況下,InnoDB 並不能徹底自動檢測到死鎖, 這須要經過設置鎖等待超時參數 innodb_lock_wait_timeout 來解決性能
innserdb避免死鎖: 一、多個事務更新相同數據的順序儘可能保持一致
二、事務開始提早顯示的獲取所有的鎖,select for update
三、選擇合適的事務大小,不要太大
四、合理設計索引
事務:
一組sql構成一個單元,要不所有執行要不一條都不執行\
特性:
原子性:一個事務(transaction)中的全部操做,要麼所有完成,要麼所有不完成,不會結束在中間某個環節。事務在執行過程當中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務歷來沒有執行過同樣
一致性:在事務開始以前和事務結束之後,數據庫的完整性沒有被破壞。這表示寫入的資料必須徹底符合全部的預設規則,這包含資料的精確度、串聯性以及後續數據庫能夠自發性地完成預約的工做
隔離性:數據庫容許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性能夠防止多個事務併發執行時因爲交叉執行而致使數據的不一致。事務隔離分爲不一樣級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)
持久性:事務處理結束後,對數據的修改就是永久的,即使系統故障也不會丟失。
髒讀:m2修改了表t1的數據還沒有提交事務,此時m1讀取了t1表中的數據,而後m2在執行後邊sql的時候出現異常,回滾了所有操做,此時m1讀取的數據即爲髒數據,即爲髒讀
不可重複讀:一個事務中,同一條查詢語句執行屢次出現了不一樣的結果。例如:事務c1查詢表t1兩次,查詢完第一次後,事務c2修改了表t1的內容並提交成功,此時c1對t1的第二次查詢跟第一次查詢的結果存在差別,即爲不可重複讀。(注意區別幻讀,幻讀的屢次查詢結果是同樣的)
幻讀:一個事務中,屢次查詢結果相同,可是根據執行結果進行操做時會出現與查詢結果不一樣的效果。例如:事務c1查詢t1中id=1的記錄是否存在,發現不存在,而後執行insert語句插入id=1的數據,此時提示主鍵重複插入失敗,再次執行select語句依然查不到id=1的數據,好像出現了幻覺,是由於有另外一個事務c2在c1執行insert以前插入了id=1的數據併成功提交了。
事務隔離級別:
讀未提交RU:一個事務m1能夠讀取到另外一個事務m2還沒有提交的數據。會產生髒讀,不可重複讀,幻讀
讀已提交RC:讀已提交,一個事務只能讀取到其餘事務提交的數據。解決髒讀,可重複讀,幻讀
可重複讀RR:一個事務中同一條查詢語句的多條查詢結果老是相同的。解決髒讀、可重複度,沒法解決幻讀;PS:可重複讀的實現原理MVCC:給每行數據添加版本號,修改時版本號+1,事務開始時記錄版本號,該事務中查詢的數據都是固定版本的內容,因此即便其餘事務成功修改提交了數據也不會影響當前事務。 能夠經過給查詢手動添加鎖(共享鎖、排他鎖)的方式解決幻讀(串行讀的實現)
select ... lock in share mode //共享鎖 select ... for update //排他鎖
串行讀serializable:不管讀寫都添加鎖,讀讀能夠共享,其餘均不可,即最後爲串行執行,解決髒讀、不可重複讀、幻讀
數據結構:B+Tree 葉子節點存儲數據(真實的數據、主鍵、地址),非葉子節點存儲索引key,每個頁子節點有一個指向相鄰節點的指針。
優勢: 一、非葉子節點只存儲key值,能夠提升每一個存儲塊(頁)的存儲數量,減小數的高度,減小磁盤IO
二、有序且相鄰的葉子節點存在指針能夠提升範圍查詢的性能
索引的查找流程:
1.索引精確查找: 肯定定位條件, 找到根節點Page No, 根節點讀到內存, 逐層向下查找, 讀取葉子節點Page,經過 二分查找找到記錄或未命中。(select * from user_info where id = 23)\
Create table table_x(int id primary key, varchar(64) name,key sec_index(name) )
• Select * from table_x where name = 「d」;
經過二級索引查出對應主鍵,拿主鍵回表查主鍵索引獲得數據, 二級索引可篩選掉大量無效記錄,提升效率
彙集索引:
索引鍵值的順序決定了表中數據的物理順序,因此一個表中只有一個彙集索引。
非彙集索引:
索引項的順序與數據的實際順序可能不一樣
聯合索引的數據結構:
聯合索引中的索引項會先根據第一個索引列進行排序,第一個索引列相同的狀況下,會再按照第二個索引列進行排序,依次類推覆蓋索引:查詢內容和查詢條件所有包含在索引中,不須要回表操做
例如:
t: id-主鍵,name:姓名,age年齡 SELECT * FROM T WHERE NAME = 'LDF' AND AGE = 20 1)沒有任何索引 全表掃描,按NAME='LDF'篩選得到一個臨時表t1,在t1的基礎上知足篩選AGE=20的數據 2)Name有索引,AGE沒有索引 搜索Name的索引文件,篩選知足Name='LDF'的索引key值,從而獲得主鍵索引的key值,根據獲得的值回表去主鍵索引中定位到具體的數據獲得臨時表t1,以t1爲基礎篩選AGE=20的數據
3)AGE有索引,Name沒有索引 同二,先搜索AGE的索引文件,篩選知足AGE的索引key值,從而獲得主鍵索引的key值,根據獲得的值回表去主鍵索引定位到具體的數據獲得臨時表t2,以t2爲基礎篩選NAME='LDF'的數據
4)NAME和AGE兩個單獨索引 MySQL 會選擇那個它認爲彷佛是最有效率的單列索引,另外的做爲普通條件過濾
5)NAME和AGE建立聯合索引 按順序先檢索name 在檢索結果中檢索age,最後獲得主鍵索引的key值回表獲取數據
一、表的數據類型遵循小而簡單的原則,越簡單的數據類型一般會越快,佔用越小的磁盤、內存,處理時須要的cpu也更少
二、一般沒有太大必要使用DECIMAL數據類型,能夠將原先的數據乘以10的n次方來存儲,避免浮點數計算不精確和decimal計算代價高的問題
三、TIMESTAMP使用四個字節,只能表示1970-2038年,datetime使用八個字節範圍要大得多 四、shcma的列不要太多,緣由是存儲引擎的API在工做時須要在服務層和存儲層之間經過行緩衝格式拷貝數據,而後在服務器層將緩衝內容解碼成各個列,轉換過程的代價很是高
五、將能篩選掉大量數據的條件放在where條件的最左側 六、select * 改成具體的字段 *意味着mysql要額外查一次元數據表,並且多餘的字段返回的數據過大影響性能 七、主鍵儘可能不要參與業務 八、建立合理的索引 1)爲常常做爲檢索條件或者排序的字段創建索引 2)不要創建過多的索引,減小磁盤佔用 3)創建索引的字段數據量不宜過大,會致使每頁的存儲量減小,從而提升了樹的高度,增長了磁盤的IO次數 4)最左前綴匹配原則,建立聯合索引時,最經常使用到的字段放在左邊 5)儘可能選擇區分度高的字段創建索引,不然對性能提交沒有太大意義 6) 索引列不能參與計算,不然會致使不走索引 7)否認的一些查詢,例如 !=. not like, is not null 會致使不走索引
ps: index 普通索引;unique 惟一索引;primary key 主鍵索引;
有的時候對應字段有索引可是查詢卻並無使用索引,這個可能緣由是由於優化器在作代價評估時認爲使用索引的代價不如不用索引因此會放棄使用。
數據文件按分區條件拆分爲小文件,就至關於大表拆成了小表,提升查詢性能。
range範圍查詢:按必定範圍分區,數字或者日期,例如partition p0 less than(10)
問題:若插入的數據不在任何範圍內會報錯。
解決:儘可能選擇能夠覆蓋整個範圍的字段做爲分區字段;使用存儲過程或者其餘方式及時增長分區;less than maxValue
list分區:按列表範圍分區,例如 partition p1 values in (1,2,3)
問題:插入的數據不在任何分區範圍內會報錯
解決:使用過程或其餘方式及時增長分區
hash分區:分散熱點數據,使數據在各個分區儘可能分佈均勻,常規hash(取模)線性hash;hash分區只能支持整數,能夠自定義分區函數
常規hash:partition by hash(store_id) partitions 4;在分區變更時,整個數據要從新分區,代價比較大\
線性hash:分區數據不大均衡
key分區: 相似hash分區,不支持自定義函數只能使用默認的函數,支持除blob和text以外的其餘類型 partition by key(exp) partitions 4;
分區表的索引:若是定義的索引列和分區列不匹配,則會致使查詢沒法進行分區過濾。例如在列a上定義分區,在列b上定義索引,由於每一個分區都有獨立的索引,因此掃描索引時須要掃描每一個分區。 應該避免創建和分區列不匹配的索引,除非查詢中包含了能夠過濾分區的條件。
主從複製: mysql從庫經過讀取主庫產生的sql操做日誌,將在主庫上執行過的sql在從庫上執行一遍