常见Sql面试题及答案
答案是自己理解整理的。。。。。。。。。。。。
?
1、MySQL的復制原理以及流程
復制有三個步驟:
1、Master將數據改變記錄到二進制日志(binary log)中,也就是配置文件log-bin指定的文件,這些記錄叫做二進制日志事件(binary log events)
2、Slave通過I/O線程讀取Master中的binary log events并寫入到它的中繼日志(relay log)
3、Slave重做中繼日志中的事件,把中繼日志中的事件信息一條一條的在本地執行一次,完成數據在本地的存儲,從而實現將改變反映到它自己的數據(數據重放)
?
?
2、MySQL中myisam與innodb的區別,至少5點
(1)、問5點不同;
1、MyISAM不支持事務,InnoDB是事務類型的存儲引擎,當我們的表需要用到事務支持的時候,那肯定是不能選擇MyISAM了。
2、MyISAM只支持表級鎖,BDB支持頁級鎖和表級鎖默認為頁級鎖,而InnoDB支持行級鎖和表級鎖默認為行級鎖
3、MyISAM引擎不支持外鍵,InnoDB支持外鍵
4、MyISAM引擎的表在大量高并發的讀寫下會經常出現表損壞的情況
5、對于count()查詢來說MyISAM更有優勢
6、 InnoDB是為處理巨大數據量時的最大性能設計,它的CPU效率可能是任何其它基于磁盤的關系數據庫引擎所不能匹敵的。
7、MyISAM支持全文索引(FULLTEXT),InnoDB不支持
8、MyISAM引擎的表的查詢、更新、插入的效率要比InnoDB高
(2)、innodb引擎的關鍵特性
一、插入緩沖: 對于非聚集索引的插入和更新,不是每一次直接插入索引頁中,而是首先判斷插入的非聚集索引頁是否在緩沖池中,如果在,則直接插入,否則,先放入一個插入緩沖區中。好似欺騙數據庫這個非聚集的索引已經插入到葉子節點了,然后再以一定的頻率執行插入緩沖和非聚集索引頁子節點的合并操作,這時通常能將多個插入合并到一個操作中,這就大大提高了對非聚集索引執行插入和修改操作的性能。(插入緩沖使用的條件:1、索引是輔助索引;?2、索引不是唯一的;)
二、二次寫:主要用于數據恢復。Double write由兩部分組成,一部分是內存中的 double write buffer。 另一部分是在物理磁盤上的共享表空間中的連續128個頁,大小和內存中(2M)一致。對緩沖池中的頁進行刷新時,并不直接寫磁盤,而是memcpy到double write buffer. 之后通過 double write buffer 分兩次,每次順序寫入共享表空間1M數據,然后馬上調用fsync同步磁盤。這個寫入因為共享表空間的double write頁是連續的,因此開銷不是很大。而完成 double write 頁的寫入后,再將double write buffer中的頁寫入各個表空間則是離散的寫入。
如果操作系統在將頁寫入磁盤的過程中發生了崩潰。那么恢復時則可以從共享表空間中double write buffer頁找到該頁的副本。將其復制到表空間再應用重做日志。
三、自適應哈希:
InnoDB存儲引擎會監控對表上索引的查找,如果觀察到建立哈希索引可以帶來速度的提升,則建立哈希索引,所以稱之為自適應(adaptive)的。
自適應哈希索引通過緩沖池的B+樹構造而來,因此建立的速度很快。而且不需要將整個表都建哈希索引,InnoDB存儲引擎會自動根據訪問的頻率
限制
1.只能用于等值比較,例如=, <=>,in
2.無法用于排序
3.有沖突可能
4.Mysql自動管理,人為無法干預。
四、異步IO
優勢:?
1. IO 并行:IO 操作可以并行發出,不必等待前面的IO完成?
2. IO Merge操作:將多個IO合并成一個IO,提高IOPS的性能
Native AIO只支持Window和Linux,Mac OSX不支持?
在Innodb存儲引擎中,read ahead方式的讀取、臟頁的刷新、磁盤的寫入都是有AIO方式完成
五、刷新臨近頁
當刷新一個臟頁的時候,Innodb存儲引擎會檢測該頁所在區的所有頁,如果都是臟頁,使用AIO的IO Merge,一起刷新至磁盤
注意問題:?
1. 一個不怎么臟的頁,相對與一個被修改多次很臟的頁,刷新是否值得。?
2. 固態硬盤有著較高的IOPS,建議不開啟。(IOPS (Input/Output Operations Per Second),即每秒進行讀寫(I/O)操作的次數,多用于數據庫等場合,衡量隨機訪問的性能)
(3)、2者selectcount(*)哪個更快,為什么
myisam更快,因為它已經存了這個count,不用像innodb那樣去真正查詢行數
3、MySQL中varchar與char的區別以及varchar(50)中的50代表的涵義
(1)、varchar與char的區別
varchar可變長度,char定長
(2)、varchar(50)中50的涵義
最大可存入50個字節。
(3)、int(20)中20的涵義
最大可存入20位數。
是指顯示字符的長度 不影響內部存儲,只是影響帶 zerofill 定義的 int 時,前面補多少個 0,易于報表展示(4)、mysql為什么這么設計
對大多數應用沒有意義,只是規定一些工具用來顯示字符的個數;int(1)和int(20)存儲和計算均一樣;4、問了innodb的事務與日志的實現方式
(1)、有多少種日志;
重做日志redo和回滾日志undo
(2)、事務的4種隔離級別
未提交讀,已提交讀,可重復讀,序列化讀
(3)、事務是如何通過日志來實現的,說得越深入越好。
一般情況下,mysql在崩潰之后,重啟服務,innodb通過回滾日志undo將所有已完成并寫入磁盤的未完成事務進行rollback,然后redo中的事務全部重新執行一遍即可恢復數據,但是隨著redo的量增加,每次從redo的第一條開始恢復就會浪費長的時間,所以引入了checkpoint機制。Checkpoint:如果在某個時間點,臟頁的數據被刷新到了磁盤,系統就把這個刷新的時間點記錄到redo log的結尾位置,在進行恢復數據的時候,checkpoint時間點之前的數據就不需要進行恢復了,可以縮短時間v
5、問了MySQL binlog的幾種日志錄入格式以及區別
(1)、binlog的日志格式的種類和分別
1.Statement:每一條會修改數據的sql都會記錄在binlog中。 2.Row:不記錄sql語句上下文相關信息,僅保存哪條記錄被修改。 3.Mixedlevel: 是以上兩種level的混合使用,一般的語句修改使用statment格式保存binlog,如一些函數,statement無法完成主從復制的操作,則 采用row格式保存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式。也就是在Statement和Row之間選擇 一種.新版本的MySQL中隊row level模式也被做了優化,并不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄。至于update或者delete等修改數據的語句,還是會記錄所有行的變更。(2)、適用場景;
在一條 SQL 操作了多行數據時, statement 更節省空間, row 更占用空間。但是 row模式更可靠。(3)、結合第一個問題,每一種日志格式在復制中的優劣。
Statement 可能占用空間會相對小一些,傳送到 slave 的時間可能也短,但是沒有 row模式的可靠。 Row 模式在操作多行數據時更占用空間, 但是可靠。6、問了下MySQL數據庫cpu飆升到500%的話他怎么處理?
當 cpu 飆升到 500%時,先用操作系統命令 top 命令觀察是不是 mysqld 占用導致的,如果不是,找出占用高的進程,并進行相關處理。如果是 mysqld 造成的, show processlist,看看里面跑的 session 情況,是不是有消耗資源的 sql 在運行。找出消耗高的 sql, 看看執行計劃是否準確, index 是否缺失,或者實在是數據量太大造成。一般來說,肯定要 kill 掉這些線程(同時觀察 cpu 使用率是否下降),等進行相應的調整(比如說加索引、改 sql、改內存參數)之后,再重新跑這些 SQL。也有可能是每個 sql 消耗資源并不多,但是突然之間, 有大量的 session 連進來導致 cpu 飆升,這種情況就需要跟應用一起來分析為何連接數會激增,再做出相應的調整,比如說限制連接數等。7、sql優化
(1)、explain出來的各種item的意義;
(2)、profile的意義以及使用場景;
?
8、備份計劃,mysqldump以及xtranbackup的實現原理
(1)、備份計劃;
視庫的大小來定,一般來說 100G 內的庫,可以考慮使用 mysqldump 來做,因為 mysqldump更加輕巧靈活,備份時間選在業務低峰期,可以每天進行都進行全量備份(mysqldump 備份 出來的文件比較小,壓縮之后更小)。100G 以上的庫,可以考慮用 xtranbackup 來做,備份速度明顯要比 mysqldump 要快。一般是選擇一周一個全備,其余每天進行增量備份,備份時間為業務低峰期。(2)、備份恢復時間;
物理備份恢復快,邏輯備份恢復慢 這里跟機器,尤其是硬盤的速率有關系,以下列舉幾個僅供參考 20G的2分鐘(mysqldump) 80G的30分鐘(mysqldump) 111G的30分鐘(mysqldump) 288G的3小時(xtra) 3T的4小時(xtra) 邏輯導入時間一般是備份時間的5倍以上(3)、xtrabackup實現原理
mysqldump
mysqldump 屬于邏輯備份。加入--single-transaction 選項可以進行一致性備份。后臺進程會先設置 session 的事務隔離級別為 RR(SET SESSION TRANSACTION ISOLATION LEVELREPEATABLE READ), 之后顯式開啟一個事務(START TRANSACTION /*!40100 WITH CONSISTENTSNAPSHOT */),這樣就保證了該事務里讀到的數據都是事務事務時候的快照。之后再把表的數據讀取出來。 如果加上--master-data=1 的話,在剛開始的時候還會加一個數據庫的讀鎖 (FLUSH TABLES WITH READ LOCK),等開啟事務后,再記錄下數據庫此時 binlog 的位置(showmaster status),馬上解鎖,再讀取表的數據。等所有的數據都已經導完,就可以結束事務Xtrabackup:
xtrabackup 屬于物理備份,直接拷貝表空間文件,同時不斷掃描產生的 redo 日志并保存下來。最后完成 innodb 的備份后,會做一個 flush engine logs 的操作(老版本在有 bug,在5.6 上不做此操作會丟數據),確保所有的 redo log 都已經落盤(涉及到事務的兩階段提交 概念,因為 xtrabackup 并不拷貝 binlog,所以必須保證所有的 redo log 都落盤,否則可能會丟最后一組提交事務的數據)。這個時間點就是 innodb 完成備份的時間點,數據文件雖然不是一致性的,但是有這段時間的 redo 就可以讓數據文件達到一致性(恢復的時候做的事 情)。然后還需要 flush tables with read lock,把 myisam 等其他引擎的表給備份出來,備份完后解鎖。 這樣就做到了完美的熱備。9、mysqldump中備份出來的sql,如果我想sql文件中,一行只有一個insert....value()的話,怎么辦?如果備份需要帶上master的復制點信息怎么辦?
10、500臺db,在最快時間之內重啟
可以使用批量 ssh 工具 pssh 來對需要重啟的機器執行重啟命令。 也可以使用 salt(前提是客戶端有安裝 salt)或者 ansible( ansible 只需要 ssh 免登通了就行)等多線程工具同時操作多臺服務器14、你們數據庫是否支持emoji表情,如果不支持,如何操作?
mysql數據庫的默認字符集utf8,只能存儲3個字節的數據。標準的emoji表情是4個字節,在APP端輸入保存表情是用戶的普遍需求和行為。
?解決方式:更換字符集utf8-->utf8mb4 ?? ? mb4的意思是most bytes 4,專門為兼容四個字節的。utf8mb4是向下兼容utf8的,所以即便修改了字段的字符集也不會影響線上數據。用java查詢的時候如果有必要,也要設置下字符集=
17、表中有大字段X(例如:text類型),且字段X不會經常更新,以讀為為主,請問
答:拆帶來的問題:連接消耗 + 存儲拆分空間;不拆可能帶來的問題:查詢性能; 如果能容忍拆分帶來的空間問題,拆的話最好和經常要查詢的表的主鍵在物理結構上放置在一起(分區) 順序IO,減少連接消耗,最后這是一個文本列再加上一個全文索引來盡量抵消連接消耗 如果能容忍不拆分帶來的查詢性能損失的話:上面的方案在某個極致條件下肯定會出現問題,那么不拆就是最好的選擇18、MySQL中InnoDB引擎的行鎖是通過加在什么上完成(或稱實現)的?為什么是這樣子的?
答:InnoDB是基于索引來完成行鎖 例: select * from tab_with_index where id = 1 for update; for update 可以根據條件來完成行鎖鎖定,并且 id 是有索引鍵的列, 如果 id 不是索引鍵那么InnoDB將完成表鎖,,并發將無從談起?
總結
以上是生活随笔為你收集整理的常见Sql面试题及答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据分析sql面试必会6题经典_经典SQ
- 下一篇: 分布式概念及相关的名词定义