一、數據庫隔離級別有哪些,各自的含義是什麼,MYSQL默認的隔離級別是是什麼。
Read uncommitted:讀未提交,顧名思義,就是一個事務能夠讀取另外一個未提交事務的數據。html
Read committed:讀提交,顧名思義,就是一個事務要等另外一個事務提交後才能讀取數據。java
Repeatable read:重複讀,就是在開始讀取數據(事務開啓)時,再也不容許修改操做。mysql
Serializable 序列化:Serializable 是最高的事務隔離級別,在該級別下,事務串行化順序執行,能夠避免髒讀、不可重複讀與幻讀。可是這種事務隔離級別效率低下,比較耗數據庫性能,通常不使用。程序員
值得一提的是:大多數數據庫默認的事務隔離級別是Read committed,好比Sql Server , Oracle。Mysql的默認隔離級別是Repeatable read。golang
二、什麼是幻讀。算法
幻讀 : 是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的所有數據行。 同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,之後就會發生操做第一個事務的用戶發現表中還有沒有修改的數據行,就好象 發生了幻覺同樣。sql
例如:程序員某一天去消費,花了2千元,而後他的妻子去查看他今天的消費記錄(全表掃描FTS,妻子事務開啓),看到確實是花了2千元,就在這個時候,程序員花了1萬買了一部電腦,即新增INSERT了一條消費記錄,並提交。當妻子打印程序員的消費記錄清單時(妻子事務提交),發現花了1.2萬元,彷佛出現了幻覺,這就是幻讀。數據庫
三、MYSQL有哪些存儲引擎,各自優缺點。
兩種存儲引擎的大體區別表如今:數組
1)InnoDB支持事務,MyISAM不支持,這一點是很是之重要。事務是一種高級的處理方式,如在一些列增刪改中只要哪一個出錯還能夠回滾還原,而MyISAM就不能夠了。緩存
2)MyISAM適合查詢以及插入爲主的應用,InnoDB適合頻繁修改以及涉及到安全性較高的應用
3)InnoDB支持外鍵,MyISAM不支持
4)從MySQL5.5.5之後,InnoDB是默認引擎
5)InnoDB不支持FULLTEXT類型的索引
6)InnoDB中不保存表的行數,如select count() from table時,InnoDB須要掃描一遍整個表來計算有多少行,可是MyISAM只要簡單的讀出保存好的行數便可。注意的是,當count()語句包含where條件時MyISAM也須要掃描整個表。
7)對於自增加的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中能夠和其餘字段一塊兒創建聯合索引。
8)清空整個表時,InnoDB是一行一行的刪除,效率很是慢。MyISAM則會重建表。
9)InnoDB支持行鎖(某些狀況下仍是鎖整表,如 update table set a=1 where user like '%lee%'
有人說MYISAM只能用於小型應用,其實這只是一種偏見。
若是數據量比較大,這是須要經過升級架構來解決,好比分表分庫,讀寫分離,而不是單純地依賴存儲引擎。
如今通常都是選用InnoDB了,主要是MyISAM的全表鎖,讀寫串行問題,併發效率鎖表,效率低,MyISAM對於讀寫密集型應用通常是不會去選用的。
總之:
1.MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。
2.MyISAM類型的表強調的是性能,其執行速度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。
四、高併發下,如何作到安全的修改同一行數據。
1)、使用悲觀鎖。便是當前只有一個線程執行操做,排斥外部請求的修改。
2)、FIFO(First Input First Output,先進先出)緩存隊列思路。便是直接將請求放入隊列中,就不會致使某些請求永遠獲取不到鎖。有點強行將多線程變成單線程的感受
3)、使用樂觀鎖(推薦)。相對於「悲觀鎖」採用更爲寬鬆的加鎖機制,大都是採用帶版本號(Version)更新
更詳細請閱讀:
https://blog.csdn.net/riemann_/article/details/89980750
五、樂觀鎖和悲觀鎖是什麼,INNODB的標準行級鎖有哪2種,解釋其含義。
樂觀鎖(Optimistic Concurrency Control,縮寫」OCC」):是一種併發控制的方法。樂觀的認爲多用戶併發的事務在處理時不會彼此互相影響,各事務可以在使用鎖的狀況下處理各自的數據。
悲觀鎖(Pessimistic Concurrency Control,縮寫」PCC」):與樂觀鎖相對應的就是悲觀鎖。悲觀鎖就是在操做數據時,認爲此操做會出現數據衝突,因此在進行每次操做時都要經過獲取鎖才能進行對相同數據的操做,這點跟 java 中的 synchronized 很類似,因此悲觀鎖須要耗費較多的時間。
它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀鎖的不一樣的實現,它倆都屬於悲觀鎖的範疇。
六、SQL優化的通常步驟是什麼,怎麼看執行計劃,如何理解其中各個字段的含義。
【1】、經過 show status 命令瞭解各類 sql 的執行頻率。mysql 客戶端鏈接成功後,經過show [session|global] status 命令能夠提供服務狀態信息,也可使用 mysqladmin extend-status 命令獲取這些消息。
一般比較關心的是如下幾個統計參數:
1)、Com_select:執行 select 操做的次數,一次查詢只累加1。
2)、Com_insert:執行 insert 操做的次數,對於批量插入的 insert 操做,只累加一次。
3)、Com_update:執行 update 操做的次數。
4)、Com_delete:執行 delete 操做的次數。
上面這些參數對於全部存儲引擎的表操做都會進行累計。下面這幾個參數只是針對 innodb 的,累加的算法也略有不一樣:
1)、Innodb_rows_read : select 查詢返回的行數。
2)、Innodb_rows_inserted : 執行 insert 操做插入的行數。
3)、Innodb_rows_updated : 執行 update 操做更新的行數。
4)、Innodb_rows_deleted : 執行 delete 操做刪除的行數。
經過以上幾個參數,能夠很容易地瞭解當前數據庫的應用是以插入更新爲主仍是以查詢操做爲主,以及各類類型的 sql 大體的執行比例是多少。對於更新操做的計數,是對執行次數的計數,不論提交仍是回滾都會進行累加。
對於事務型的應用,經過 Com_commit 和 Com_rollback 能夠了解事務提交和回滾的狀況,對於回滾操做很是頻繁的數據庫,可能意味着應用編寫存在問題。
此外,如下幾個參數便於用戶瞭解數據庫的基本狀況:
1)、Connections : 試圖鏈接 mysql 服務器的次數
2)、Uptime : 服務器工做時間
3)、Slow_queries:慢查詢次數
【2】、查詢執行效率較低的 sql 語句:
經過慢查詢日誌定位那些執行效率較低的 sql 語句,用 --log-slow-queries[=file_name] 選項啓動時,mysqld 寫一個包含全部執行時間超過 long_query_time 秒的 sql 語句的日誌文件。
慢查詢日誌在查詢結束之後才記錄,因此在應用反映執行效率出現問題的時候慢查詢日誌並不能定位問題,可使用 show processlist 命令查看當前 mysql 在進行的線程,包括線程的狀態、是否鎖表等,能夠實時的查看 sql 的執行狀況,同時對一些鎖表操做進行優化。
【3】、經過 explain 分析低效 SQL 的執行計劃: 查詢到效率低的 SQL 語句後,能夠經過 explain 或者 desc 命令獲取 MySQL 如何執行 select 語句的信息,包括在 select 語句執行過程當中表如何鏈接和鏈接的順序。
如下是 explain 語句返回參數:
1)、 id:select 查詢的序列號,包含一組數字,表示查詢中執行 select 子句或操做表的順序。三種狀況:
①、id相同:執行順序由上而下
②、id不一樣:若是是子查詢,id 序號會遞增,id 越大優先級越高,越先被執行
③、id既有相同的也有不一樣的,二者同時存在--->id 若是相同,能夠認爲是一組,由上往下執行;在全部組裏id越大,優先級越高,越先執行。
2)、select_type:類型主要用於區別普通查詢、聯合查詢、子查詢等的複雜程度。
SIMPLE:簡單的 select 查詢,查詢中不包含子查詢或者UNION。
PRIMARY:查詢中若包含任何複雜的自查詢,最外層查詢爲 PRIMARY。
SUBQUERY:在 SELECT 或 WHERE 中包含子查詢。
DERIVED:在 FROM 列表中包含的子查詢被標記爲
DERIVED(衍生)MySQL會遞歸執行這些子查詢,把結果放進臨時表。
UNION:若第二個SELECT出如今UNION以後,則被標記爲UNION,若UNION包含在FROM子句的子查詢,則外層SELECT將被標記爲DERIVED。
UNION RESULT:從UNION表中獲取結果的SELECT。
3)、table:顯示這行數據是關於那張表的。
4)、type:主要類型以下:
從最好到最差:system > const > eq_ref > ref > range > index > ALL,通常達到 rang 級別,最好達到 ref 級別。
5)、possible_keys :顯示可能應用到這張表中的索引,查詢字段上若存在索引則列出來,但不必定被查詢實際使用。
6)、keys:實際使用的索引。若是未null,則沒有使用索引。若查詢中出現了覆蓋索引(覆蓋索引:查詢的字段和建立的索引的字段和個數徹底同樣時),則該索引只出現 key。
7)、key_len:表示索引中使用的字節數,可經過該列查找出使用索引的長度。在不損壞精準性的狀況下,長度越短越好。key_len顯示的值爲索引字段的最大可能長度,並不是實際長度,即 key_len 是根據表定義實際計算出來的,不是經過表內檢出來的。
8)、ref:顯示索引的那一列被使用,若是可能的話,是一個常數。那些列或常量被用於查找索引上的值。
9)、rows:根據表統計信息及索引選用狀況,大體估算出找到所需的記錄的行數。
10)、Extra:包含不適合在其餘列中顯示,但十分重要的信息。
七、mysql怎麼解決死鎖。
產生死鎖的四個必要條件:
①、互斥條件:一個資源每次只能被一個進程使用。
②、請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
③、不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
④、循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不知足,就不會發生死鎖。
這裏提供兩個解決數據庫死鎖的方法:
①、重啓數據庫。②、殺掉搶資源的進程
八、Mysql的索引原理,索引的類型有哪些,如何建立合理的索引,索引如何優化。
MySql索引的原理:
1)、經過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,咱們能夠總用同一種查找方式來鎖定數據。
2)、索引是經過複雜的算法,提升數據查詢性能的手段。從磁盤 io 到內存 io 的轉變。
MySql索引的類型:
1)、普通索引 index:加速查找
2)、惟一索引:
①、主鍵索引:primary key:加速查找+主鍵惟一約束且不爲空。
②、惟一索引:unique:加速查找+主鍵惟一約束。
3)、聯合索引:
①、primary key(id,name):聯合主鍵索引。
②、unique(id,name):聯合惟一索引。
③、unique(id,name):聯合普通索引。
4)、全文索引 fulltext:用於搜索很長一篇文章的時候,效果最好。
5)、空間索引 spatial:瞭解就好,幾乎不用。
九、彙集索引和非彙集索引的區別。
「聚簇」:就是索引和記錄緊密在一塊兒。
「非聚簇索引」:索引文件和數據文件分開存放,索引文件的葉子頁只保存了主鍵值,要定位記錄還要去查找相應的數據塊。
十、select for update 是什麼含義,會鎖表仍是鎖行或是其餘。
select for update 語句是咱們常用手工加鎖語句。藉助 for update 子句,咱們能夠在應用程序的層面手工實現數據加鎖保護操做。屬於併發行鎖。
十一、爲何要用Btree實現,它是怎麼分裂的,何時分裂,爲何是平衡的。
爲何使用B+樹?言簡意賅,就是由於:
1).文件很大,不可能所有存儲在內存中,故要存儲到磁盤上
2).索引的結構組織要儘可能減小查找過程當中磁盤I/O的存取次數(爲何使用B-/+Tree,還跟磁盤存取原理有關。)
3).局部性原理與磁盤預讀,預讀的長度通常爲頁(page)的整倍數,(在許多操做系統中,頁得大小一般爲4k)
4).數據庫系統巧妙利用了磁盤預讀原理,將一個節點的大小設爲等於一個頁,這樣每一個節點只須要一次I/O就能夠徹底載入,(因爲節點中有兩個數組,因此地址連續)。而紅黑樹這種結構,h明顯要深的多。因爲邏輯上很近的節點(父子)物理上可能很遠,沒法利用局部性。
Key 超過1024才分裂,由於隨着數據的增多,一個結點的 key 滿了,爲了保持 B 樹的特性,就會產生分裂,就向紅黑樹和 AVL樹爲了保持樹的性質須要進行旋轉同樣!
十二、數據庫的ACID是什麼。
A(atomic):原子性,要麼都提交,要麼都失敗,不能一部分紅功,一部分失敗。
C(consistent):一致性,事務開始及結束後,數據的一致性約束沒有被破壞
I(isolation):隔離性,併發事務間相互不影響,互不干擾。
D(durabilit):持久性,已經提交的事務對數據庫所作的更新必須永久保存。即使發生崩潰,也不能被回滾或數據丟失。
1三、某個表有近千萬數據,CRUD比較慢,如何優化。
數據千萬級別之多,佔用的存儲空間也比較大,可想而知它不會存儲在一塊連續的物理空間上,而是鏈式存儲在多個碎片的物理空間上。可能對於長字符串的比較,就用更多的時間查找與比較,這就致使用更多的時間。
1)、做爲關係型數據庫,是什麼緣由出現了這種大表?是否能夠作表拆分,減小單表字段數量,優化表結構。
2)、在保證主鍵有效的狀況下,檢查主鍵索引的字段順序,使得查詢語句中條件的字段順序和主鍵索引的字段順序保持一致。
3)、在程序邏輯中採用手動事務控制,不要每插入一條數據就自動提交,而是定義一個計數器,進行批量手動提交,可以有效提升運行速度。
更多分析可閱讀文章:
https://blog.csdn.net/riemann_/article/details/93676341
1四、Mysql怎麼優化全表掃描(table scan)的。
避免在 where 子句中對字段進行 is null 判斷。
應儘可能避免在 where 子句中使用 != 或 <> 操做符,不然將會致使引擎放棄使用索引而進行全表掃描。
避免在 where 子句中使用 or 來鏈接條件。
in 和not in 也要慎用。
Like 查詢(非左開頭)。
不要使用 NUM=@num 參數這種。
不要where 子句中對字段進行表達式操做 num/2=XX。
不要在where子句中對字段進行函數操做。
1五、如何寫sql可以有效的使用到複合索引。
因爲複合索引=組合索引,相似多個木板拼接在一塊兒,若是中間斷了就沒法用了,因此要能用到複合索引,首先開頭(第一列)要用上,好比index(a,b) 這種,咱們能夠select table tname where a=XX 用到第一列索引 若是想用第二列 能夠 and b=XX 或者and b like ‘TTT%’。
1六、mysql中in 和exists 區別。
mysql 中的 in 語句是把外表和內表做 hash 鏈接,而 exists 語句是對外表做 loop 循環,每次 loop 循環再對內表進行查詢。一直你們都認爲 exists 比 in 語句的效率要高,這種說法實際上是不許確的。這個是要區分環境的。
㊤、若是查詢的兩個表大小至關,那麼用 in 和 exists 差異不大。
㊥、若是兩個表中一個較小,一個是大表,則子查詢表大的用 exists,子查詢表小的用 in。
㊦、not in 和 not exists 若是查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而 not extsts 的子查詢依然能用到表上的索引。因此不管那個表大,用 not exists 都比 not in 要快。
EXISTS 只返回 TRUE 或 FALSE,不會返回 UNKNOWN
IN 當遇到包含NULL的狀況,那麼就會返回 UNKNOWN
1七、數據庫自增主鍵可能的問題。
【1】、使用自增主鍵對數據庫作分庫分表,可能出現一些諸如主鍵重複等的問題。
【2】、數據庫導入的時候,可能會由於主鍵出現一些問題。
可參考文章:https://yq.aliyun.com/article...
1八、你作過的項目裏遇到分庫分表了嗎,怎麼作的,有用到中間件麼,好比sharding jdbc等,它們的原理知道麼。
參考文章:
http://www.javashuo.com/article/p-shltcojm-hg.html
1九、MYSQL的主從延遲怎麼解決。
實際上主從同步延遲根本沒有什麼一招制敵的辦法,由於全部的 SQL 必須都要在從服務器裏面執行一遍,可是主服務器若是不斷的有更新操做源源不斷的寫入, 那麼一旦有延遲產生,那麼延遲加劇的可能性就會愈來愈大。 固然咱們能夠作一些緩解的措施。
a)、最簡單的減小 slave 同步延時的方案就是在架構上作優化,儘可能讓主庫的 DDL 快速執行。還有就是主庫是寫,對數據安全性較高,好比 sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設置,而 slave 則不須要這麼高的數據安全,徹底能夠將 sync_binlog 設置爲 0 或者關閉 binlog,innodb_flushlog 也能夠設置爲 0 來提升 sql 的執行效率。另外就是使用比主庫更好的硬件設備做爲 slave。
b)、把一臺從服務器看成備份使用, 而不提供查詢, 這樣他的負載就下來了, 執行 relay log 裏面的 SQL 效率天然就高了。
c)、增長從服務器,這個目的仍是分散讀的壓力, 從而下降服務器負載。
更多優秀文章:
http://www.javashuo.com/article/p-kfmtfuup-bv.html
http://www.javashuo.com/article/p-dgoxumww-k.html
https://studygolang.com/articles/14834