Java面試題2.0--mysql

 

歡迎關注《Java面試題2.0》合集發佈頁,持續更新中!

 
MySQL如何優化
 
表的設計合理化(符合3NF)
添加適當索引(index) [四種: 普通索引、主鍵索引、唯一索引unique、全文索引]
SQL語句優化
分表技術(水平分割、垂直分割)
讀寫[寫: update/delete/add]分離
存儲過程 [模塊化編程,可以提高速度]
對mysql配置優化 [配置最大併發數my.ini, 調整緩存大小 ]
mysql服務器硬件升級
定時的去清除不需要的數據,定時進行碎片整理(MyISAM)
 
子查詢變成left join
limit 分佈優化,先利用ID定位,再分頁
or條件優化,多個or條件可以用union all對結果進行合併(union all結果可能重複)
不必要的排序
where代替having,having 檢索完所有記錄,才進行過濾
避免嵌套查詢
對多個字段進行等值查詢時,聯合索引
 
SQL優化技巧
 
①使用group by 分組查詢是,默認分組後,還會排序,可能會降低速度,
在group by 後面增加 order by null 就可以防止排序.
explain select * from emp  group by deptno order by null;
②有些情況下,可以使用連接來替代子查詢。因爲使用join,MySQL不需要在內存中創建臨時表。
select * from dept, emp where dept.deptno=emp.deptno; [簡單處理方式]
select * from dept left join emp on dept.deptno=emp.deptno;  [左外連接,更ok!]
 
③對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引
應儘量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
最好不要給數據庫留 NULL,儘可能的使用 NOT NULL 填充數據庫.
備註、描述、評論之類的可以設置爲 NULL,其他的,最好不要使用 NULL。
不要以爲 NULL 不需要空間,比如:char(100) 型,在字段建立時,空間就固定了, 不管是否插入值(NULL 也包含在內),都是佔用 100 個字符的空間的,如果是 varchar 這樣的變長字段, null 不佔用空間。
可以在 num 上設置默認值 0,確保表中 num 列沒有 null 值,然後這樣查詢:
select id from t where num = 0
更多mysql sql語句調優查看http://bbs.itmayiedu.com/article/1511164574773
 
優化SQL語句的一般步驟
 
1.通過show status命令瞭解各種SQL的執行頻率
 
2.定位執行效率較低的SQL語句
 
3.通過explain分析低效SQL的執行計劃
 
4.確定問題並採取相應的優化措施
 
數據庫會死鎖嗎
 
 
什麼是數據庫範式
 
爲了建立冗餘較小、結構合理的數據庫,設計數據庫時必須遵循一定的規則。在關係型數據庫中這種規則就稱爲範式。範式是符合某一種設計要求的總結。要想設計一個結構合理的關係型數據庫,必須滿足一定的範式。
數據庫三大範式
第一範式:1NF是對屬性的原子性約束,要求屬性(列)具有原子性,不可再分解;(只要是關係型數據庫都滿足1NF)
第二範式:2NF是對記錄的惟一性約束,表中的記錄是唯一的, 就滿足2NF, 通常我們設計一個主鍵來實現,主鍵不能包含業務邏輯。
第三範式:3NF是對字段冗餘性的約束,它要求字段沒有冗餘。 沒有冗餘的數據庫設計可以做到。
但是,沒有冗餘的數據庫未必是最好的數據庫,有時爲了提高運行效率,就必須降低範式標準,適當保留冗餘數據。具體做法是: 在概念數據模型設計時遵守第三範式,降低範式標準的工作放到物理數據模型設計時考慮。降低範式就是增加字段,允許冗餘。
 
分表分庫
 
垂直拆分
 
垂直拆分就是要把表按模塊劃分到不同數據庫表中(當然原則還是不破壞第三範式)。把原來強耦合的系統拆分成多個弱耦合的服務,通過服務間的調用來滿足業務需求看,因此表拆出來後要通過服務的形式暴露出去,而不是直接調用不同模塊的表,
 
水平拆分
 
上面談到垂直切分只是把表按模塊劃分到不同數據庫,但沒有解決單表大數據量的問題,而水平切分就是要把一個表按照某種規則把數據劃分到不同表或數據庫裏。例如像計費系統,通過按時間來劃分表就比較合適,因爲系統都是處理某一時間段的數據。而像SaaS應用,通過按用戶維度來劃分數據比較合適,因爲用戶與用戶之間的隔離的,一般不存在處理多個用戶數據的情況,簡單的按user_id範圍來水平切分
通俗理解:水平拆分行,行數據拆分到不同表中, 垂直拆分列,表數據拆分到不同表中
 
如何使用水平拆分數據庫
 
使用水平分割拆分表,具體根據業務需求,有的按照註冊時間、取摸、賬號規則、年份、哈希等。
 
SQL優化
如何從一個大項目中,迅速的定位執行速度慢的語句. (定位慢查詢)
 
show status
使用show status使用show status查看MySQL服務器狀態信息
 
什麼是慢查詢
 
  MySQL默認10秒內沒有響應SQL結果,則爲慢查詢
可以去修改MySQL慢查詢默認時間
 
什麼是索引
 
索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的所有記錄,直至找到符合要求的記錄。表裏面的記錄數量越多,這個操作的代價就越高。如果作爲搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。 
 
 
主鍵索引
 
主鍵是一種唯一性索引,但它必須指定爲“PRIMARY KEY”。如果你曾經用過AUTO_INCREMENT類型的列,你可能已經熟悉主鍵之類的概念了。主鍵一般在創建表的時候指定,
 
唯一索引
 
這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。
 
普通索引
 
 普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對數據的訪問速度。因此,應該只爲那些最經常出現在查詢條件(WHEREcolumn=)或排序條件(ORDERBYcolumn)中的數據列創建索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如一個整數類型的數據列)來創建索引。
 
 
索引原理
 
數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用 B 樹及其變種 B+ 樹。
在數據之外,數據庫系統還維護着滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找算法。這種數據結構,就是索引。
爲表設置索引要付出代價的:一是增加了數據庫的存儲空間,二是在插入和修改數據時要花費較多的時間(因爲索引也要隨之變動)。
 
索引的好處:
 
創建索引可以大大提高系統的性能。
第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
第二,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
 
壞處:
 
第一,創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。
第二,索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。
第三,當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
 
不應該創建索引的的特點:
 
第一,對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
第二,對於那些只有很少數據值的列也不應該增加索引。這是因爲,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。
第三,對於那些定義爲 text, image 和 bit 數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。
第四,當修改性能遠遠大於檢索性能時,不應該創建索引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。
 
那些列上適合添加索引
 
查詢作爲查詢條件字段應該創建索引
唯一性太差的字段不適合單獨創建索引,即使頻繁
Select * from emp where sex=’男’
頻繁更新字段,也不要定義索引。
不會出現在where語句的字段不要創建索引
 
總結:滿處一下條件的字段,才應該創建索引
①肯定在where條件經常使用
②該字段的內容不是唯一的幾個值
③字段內容不是頻繁變化
 
最左匹配原則
 
最左匹配原則是針對索引的
舉例來說:兩個字段(name,age)建立聯合索引,如果where age=12這樣的話,是沒有利用到索引的,
這裏我們可以簡單的理解爲先是對name字段的值排序,然後對age的數據排序,如果直接查age的話,這時就沒有利用到索引了,
查詢條件where name=‘xxx’ and age=xx 這時的話,就利用到索引了,再來思考下where age=xx and name=’xxx‘ 這個sql會利用索引嗎,
按照正常的原則來講是不會利用到的,但是優化器會進行優化,把位置交換下。這個sql也能利用到索引了
 
B 樹
 
B 樹中每個節點包含了鍵值和鍵值對於的數據對象存放地址指針,所以成功搜索一個對象可以不用到達樹的葉節點。
成功搜索包括節點內搜索和沿某一路徑的搜索,成功搜索時間取決於關鍵碼所在的層次以及節點內關鍵碼的數量。
 
B+樹的實現
 
一個m階的B+樹具有如下幾個特徵:
1.有k個子樹的中間節點包含有k個元素(B樹中是k-1個元素),每個元素不保存數據,只用來索引,所有數據都保存在葉子節點。
2.所有的葉子結點中包含了全部元素的信息,及指向含這些元素記錄的指針,且葉子結點本身依關鍵字的大小自小而大順序鏈接。
3.所有的中間節點元素都同時存在於子節點,在子節點元素中是最大(或最小)元素
 
爲什麼使用B+Tree
 
索引查找過程中就要產生磁盤I/O消耗,主要看IO次數,和磁盤存取原理有關。
根據B-Tree的定義,可知檢索一次最多需要訪問h個節點。數據庫系統的設計者巧妙利用了磁盤預讀原理,
將一個節點的大小設爲等於一個頁,這樣每個節點只需要一次I/O就可以完全載入
局部性原理與磁盤預讀
 
索引的底層實現(B+樹,爲何不採用紅黑樹,B樹
 
紅黑樹                 增加,刪除,紅黑樹會進行頻繁的調整,來保證紅黑樹的性質,浪費時間
B樹也就是B-樹    B樹,查詢性能不穩定,查詢結果高度不致,每個結點保存指向真實數據的指針,相比B+樹每一層每屋存儲的元素更多,顯得更高一點。
B+樹                   B+樹相比較於另外兩種樹,顯得更矮更寬,查詢層次更淺
 
索引注意事項:
 
1.對於創建的多列索引,如果不是使用第一部分,則不會創建索引。
explain select * from dept where loc='aaa'\G
就不會使用到索引
2.模糊查詢在like前面有百分號開頭會失效。
3. 如果條件中有or,即使其中有條件帶索引也不會使用。換言之,就是要求使用的所有字段,都必須建立索引, 我們建議大家儘量避免使用or 關鍵字
4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。(添加時,字符串必須’’), 也就是,如果列是字符串類型,就一定要用 ‘’ 把他包括起來.
5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引。
 
使用EXPLAIN查看執行過程
 
主從複製
 
MySQL主從複製是其最重要的功能之一。主從複製是指一臺服務器充當主數據庫服務器,另一臺或多臺服務器充當從數據庫服務器,主服務器中的數據自動複製到從服務器之中。對於多級複製,數據庫服務器即可充當主機,也可充當從機。MySQL主從複製的基礎是主服務器對數據庫修改記錄二進制日誌,從服務器通過主服務器的二進制日誌自動執行更新。
 
Mysq主從複製的類型
 
基於語句的複製:
 
主服務器上面執行的語句在從服務器上面再執行一遍,在MySQL-3.23版本以後支持。
 
存在的問題:時間上可能不完全同步造成偏差,執行語句的用戶也可能是不同一個用戶。
 
基於行的複製
 
把主服務器上面改編後的內容直接複製過去,而不關心到底改變該內容是由哪條語句引發的,在MySQL-5.0版本以後引入。
 
存在的問題:比如一個工資表中有一萬個用戶,我們把每個用戶的工資+1000,那麼基於行的複製則要複製一萬行的內容,由此造成的開銷比較大,而基於語句的複製僅僅一條語句就可以了。
 
混合類型的複製
 
MySQL默認使用基於語句的複製,當基於語句的複製會引發問題的時候就會使用基於行的複製,MySQL會自動進行選擇。
 
在MySQL主從複製架構中,讀操作可以在所有的服務器上面進行,而寫操作只能在主服務器上面進行。主從複製架構雖然給讀操作提供了擴展,可如果寫操作也比較多的話(多臺從服務器還要從主服務器上面同步數據),單主模型的複製中主服務器勢必會成爲性能瓶頸。
 
 
解決問題
數據如何不被丟失
備份
讀寫分離
數據庫負載均衡
高可用
 
主從複製原理
 
依賴於二進制日誌,binary-log.
二進制日誌中記錄引起數據庫發生改變的語句
 
 
Scale-up與Scale-out區別
 
Scale Out是指Application可以在水平方向上擴展。一般對數據中心的應用而言,Scale out指的是當添加更多的機器時,應用仍然可以很好的利用這些機器的資源來提升自己的效率從而達到很好的擴展性。
Scale Up是指Application可以在垂直方向上擴展。一般對單臺機器而言,Scale Up值得是當某個計算節點(機器)添加更多的CPU Cores,存儲設備,使用更大的內存時,應用可以很充分的利用這些資源來提升自己的效率從而達到很好的擴展性。
 
 
什麼是讀寫分離
 
在數據庫集羣架構中,讓主庫負責處理事務性查詢,而從庫只負責處理select查詢,讓兩者分工明確達到提高數據庫整體讀寫性能。當然,主數據庫另外一個功能就是負責將事務性查詢導致的數據變更同步到從庫中,也就是寫操作。
讀寫分離的好處
 1)分攤服務器壓力,提高機器的系統處理效率
2)增加冗餘,提高服務可用性,當一臺數據庫服務器宕機後可以調整另外一臺從庫以最快速度恢復服務
 
讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操作。數據庫複製被用來把事務性操作導致的變更同步到集羣中的從數據庫。
 
爲什麼要讀寫分離呢?
 
因爲數據庫的“寫”操作是比較耗時的。
但是數據庫的“讀”會要求很快。
所以讀寫分離,解決的是,數據庫的寫入,影響了查詢的效率。
 
什麼時候要讀寫分離?
 
數據庫不一定要讀寫分離,如果程序使用數據庫較多時,而更新少,查詢多的情況下會考慮使用,利用數據庫 主從同步 。可以減少數據庫壓力,提高性能。當然,數據庫也有其它優化方案。memcache 或是 表折分,或是搜索引擎。都是解決方法。
 
主從複製與讀寫分離
 
在實際的生產環境中,對數據庫的讀和寫都在同一個數據庫服務器中,是不能滿足實際需求的。無論是在安全性、高可用性還是高併發等各個方面都是完全不能滿足實際需求的。因此,通過主從複製的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力。有點類似於前面我們學習過的rsync,但是不同的是rsync是對磁盤文件做備份,而mysql主從複製是對數據庫中的數據、語句做備份。
 
mysql讀寫分離原理
 
讀寫分離就是在主服務器上修改,數據會同步到從服務器,從服務器只能提供讀取數據,不能寫入,實現備份的同時也實現了數據庫性能的優化,以及提升了服務器安全。
 
常見的Mysql讀寫分離分爲以下兩種:
 
1、基於程序代碼內部實現
在代碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是性能較好,因爲程序在代碼中實現,不需要增加額外的硬件開支,缺點是需要開發人員來實現,運維人員無從下手。
 
2、基於中間代理層實現
代理一般介於應用服務器和數據庫服務器之間,代理數據庫服務器接收到應用服務器的請求後根據判斷後轉發到,後端數據庫,有以下代表性的程序。
 
什麼是  Mycat
 
是一個開源的分佈式數據庫系統,但是因爲數據庫一般都有自己的數據庫引擎,而Mycat並沒有屬於自己的獨有數據庫引擎,所有嚴格意義上說並不能算是一個完整的數據庫系統,只能說是一個在應用和數據庫之間起橋樑作用的中間件。
在Mycat中間件出現之前,MySQL主從複製集羣,如果要實現讀寫分離,一般是在程序段實現,這樣就帶來了一個問題,即數據段和程序的耦合度太高,如果數據庫的地址發生了改變,那麼我的程序也要進行相應的修改,如果數據庫不小心掛掉了,則同時也意味着程序的不可用,而對於很多應用來說,並不能接受;
 
  引入Mycat中間件能很好地對程序和數據庫進行解耦,這樣,程序只需關注數據庫中間件的地址,而無需知曉底層數據庫是如何提供服務的,大量的通用數據聚合、事務、數據源切換等工作都由中間件來處理;
  Mycat中間件的原理是對數據進行分片處理,從原有的一個庫,被切分爲多個分片數據庫,所有的分片數據庫集羣構成完成的數據庫存儲,有點類似磁盤陣列中的RAID0.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章