mysql面試題mysql
1. 各個數據庫存儲引擎區別
mysql的存儲引擎是針對表進行設置的,一個庫的不一樣表能夠設置不一樣的存儲引擎,mysql默認支持多種存儲引擎,以適用不一樣領域的數據庫應用須要,主要的幾個數據庫引擎以下:
MyISAM存儲引擎
5.5以前默認的存儲引擎,不支持事務、不支持外鍵,表級鎖,內存和硬盤空間佔用率低,其優點是訪問速度快,對事務完整性沒有要求,以select、insert爲主的應用基本上均可以使用這個引擎;
InnoDB存儲引擎
5.5以後默認的存儲引擎,提供了具備提交、回滾和奔潰恢復能力的事務安全,支持外鍵並提供了行級鎖,其劣勢在於寫的處理效率相對較低,而且會佔用更多的磁盤空間以保留數據和索引;面試
MEMORY存儲引擎
使用存於內存中的內容來建立表,MEMORY類型的表數據存於內存訪問很是的快,默認使用HASH索引,一旦數據庫服務重啓或關閉,表中的數據就會丟失;
MERGE存儲引擎
MERGE存儲引擎是一組MyISAM表組合,這些MyISAM表結構徹底相同。MERGE表自己沒有數據,對MERGE表的CRUD操做都是經過內部的MyISAM表進行的;redis
2. 提升sql 語句效率的技巧
大批量插入數據
大批量數據插入空表,可將表設置成爲MyISAM,並經過disable keys將惟一索引關閉;
大批量數據插入非空Innodb表,可採起以下措施提升效率:
1. 導入數據時按照主鍵順序排列;
2. 導入數據前使用set UNIQUE_CHECKS=0,關閉惟一性校驗,導入後恢復;
3. 若是使用了自動提交,建議在導入前執行SET AUTOCOMMIT=0,關閉自動提交,導入後恢復;
優化INSERT 語句
儘可能使用多個值表的insert語句,下降鏈接、關閉的消耗;
將索引文件和數據文件分在不一樣的磁盤上存放;
從一個文本文件裝入一個表時,使用LOAD DATA INFLIE ,比通常的insert語句快20倍;sql
查詢優化
儘可能減小額外的排序,經過索引直接返回有序數據;where條件和order by使用相同的索引,而且order by的順序與索引順序相同,而且order by的字段都是升序或者都是降序;
儘可能只選擇必要的字段,提升sql性能;
能用關聯查詢的不要用子查詢;
對於包含or的查詢語句,若是要利用索引,則or之間的每一個條件都必須用到索引,不然應該考慮增長索引;
優化分頁
在索引上完成排序分頁的操做,而後根據主鍵關聯回原表查詢所需的其餘列
把limit查詢轉換爲某個位置的查詢;mongodb
注意不使用索引的狀況
若是MySQL估計使用索引比全表掃描更慢,則不使用索引。
用or分隔開的條件,若是or前的條件中的列有索引,然後面的列沒有索引,那麼涉及到的索引都不會被用到;
複合索引,若是索引列不是複合索引的第一部分,則不使用索引(即不符合最左前綴;
若是like是以’%’開始的,則該列上的索引不會被使用。
若是列爲字符串,則where條件中必須將字符常量值加引號,不然即便該列上存在索引,也不會被使用;
not in 、 not exists 、 (<> 不等於 !=)這些操做符不走索引
不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引;數據庫
3. 怎麼樣作執行計劃分析
經過explain命令獲取mysql如何執行select語句的信息,包括在select語句執行過程當中表如何鏈接和鏈接的順序;explain分析後的結果解析:
select_type
查詢的類型,主要是用於區分普通查詢、聯合查詢、子查詢等複雜的查詢
SIMPLE:簡單的select查詢,查詢中不包含子查詢或者union
PRIMARY:查詢中包含任何複雜的子部分,最外層查詢則被標記爲primary
SUBQUERY:在select 或 where列表中包含了子查詢
UNION:若第二個select出如今union以後,則被標記爲union;若union包含在from子句的子查詢中,外層select將被標記爲derivedjson
type
訪問類型,sql查詢優化中一個很重要的指標,結果值從好到壞依次是:system > const > eq_ref > ref > range > index > ALL通常來講,好的sql 查詢至少達到range 級別,最好能達到ref ;
system:表只有一行記錄(等於系統表),這是const類型的特例,平時不會出現,能夠忽略不計
const:表示經過索引一次就找到了,const用於比較primary key 或者 unique索引。
eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配(1對1);
ref:非惟一性索引掃描,返回匹配某個單獨值的全部行。
range:索引範圍掃描;
index:索引全掃描;
ALL:全表掃描;後端
possible_keys
查詢涉及到的字段上存在索引,則該索引將被列出,但不必定被查詢實際使用
key
實際使用的索引,若是爲NULL,則沒有使用索引。
key_len
表示索引中使用的字節數,查詢中使用的索引的長度(最大可能長度),並不是實
際使用長度,理論上長度越短越好;
ref
顯示索引的哪些列;
rows
根據表統計信息及索引選用狀況,大體估算出找到所需的記錄所須要讀取的行數
Extra
不適合在其餘字段中顯示,可是十分重要的額外信息數組
優化目標 Tips:
1. 根據需求創建索引
2. 每一個查詢都要使用索引以提升查詢效率,至少達到range級別,最好能達到ref;
3. 追求key_len和rows最小;緩存
4. mysql 複製的原理
Mysql的複製原理大體以下:
1.主庫在數據提交時會把數據變動做爲事件記錄在二進制日誌文件Binlog中;可經過sync_binlog控制binlog日誌刷新到磁盤的頻率;
2.主庫推送二進制日誌文件binlog中的事件到從庫的中繼日誌Relay Log,以後從庫根據中繼日誌RelayLog重作數據變動操做,經過邏輯複製達到主從庫的數據一致;
3.MySQL經過3個線程來完成主從庫之間的數據同步,其中binlog dump線程跑在主庫上,I/O線程和sql線程跑在從庫上。
當從庫啓動複製時,首先建立I/O線程鏈接主庫,主庫隨後建立binlog dump線程讀取數據庫事件併發送給I/O線程,I/O線程獲取到事件數據後更新到從庫的中繼日誌replay log中去,以後從庫上的sql線程讀取中繼日誌中更新的數據庫事件並應用;
1. mongodb 與mysql 的區別?
mongodb的本質仍是一個數據庫產品,3.0以上版本其穩定性和健壯性有很大提高。它與mysql的區別在於它不會遵循一些約束,好比:sql標準、ACID屬性,表結構等。其主要特性以下:
面向集合文檔的存儲:適合存儲Bson(json的擴展)形式的數據;
格式自由,數據格式不固定,生產環境下修改結構均可以不影響程序運行;
強大的查詢語句,面向對象的查詢語言,基本覆蓋sql語言全部能力;
完整的索引支持,支持查詢計劃;
支持複製和自動故障轉移;
支持二進制數據及大型對象(文件)的高效存儲;
使用分片集羣提高系統擴展性;
使用內存映射存儲引擎,把磁盤的IO操做轉換成爲內存的操做;
2. mongoDB 主要使用在什麼應用場景?
MongoDB 的應用已經滲透到各個領域,好比遊戲、物流、電商、內容管理、社交、物聯網、視頻直播等,如下是幾個實際的應用案例:
遊戲場景,使用 MongoDB 存儲遊戲用戶信息,用戶的裝備、積分等直接之內嵌文檔的形式存儲,方便查詢、更新
物流場景,使用 MongoDB 存儲訂單信息,訂單狀態在運送過程當中會不斷更新,以MongoDB 內嵌數組的形式來存儲,一次查詢就能將訂單全部的變動讀取出來。
社交場景,使用 MongoDB 存儲存儲用戶信息,以及用戶發表的朋友圈信息,經過地理位置索引實現附近的人、地點等功能
物聯網場景,使用 MongoDB 存儲全部接入的智能設備信息,以及設備彙報的日誌信息,並對這些信息進行多維度的分析
視頻直播,使用 MongoDB 存儲用戶信息、禮物信息等
3. 怎麼樣作mongodb 查詢優化
第一步 找出慢速查詢
1. 開啓內置的查詢分析器,記錄讀寫操做效率:
db.setProfilingLevel(n,{m}),n的取值可選0,1,2;
0是默認值表示不記錄;
1表示記錄慢速操做,若是值爲1,m必須賦值單位爲ms,用於定義慢速查詢時間的閾值;
2表示記錄全部的讀寫操做;
例如:db.setProfilingLevel(1,300)
2. 查詢監控結果
監控結果保存在一個特殊的蓋子集合system.profile裏,這個集合分配了128kb的空間,要確保監控分析數據不會消耗太多的系統性資源;蓋子集合維護了天然的插入順序,可使用$natural操做符進行排序,如:db.system.profile.find().sort({'$natural':-1}).limit(5)
第二步 分析慢速查詢
找出慢速查詢的緣由比較棘手,緣由可能有多個:應用程序設計不合理、不正確的數據模型、硬件配置問題,缺乏索引等;接下來對於缺乏索引的狀況進行分析:使用explain分析慢速查詢
例如:db.orders.find({'price':{'$lt':2000}}).explain('executionStats')
explain的入參可選值爲:
"queryPlanner" 是默認值,表示僅僅展現執行計劃信息;
"executionStats" 表示展現執行計劃信息同時展現被選中的執行計劃的執行狀況信息;
"allPlansExecution" 表示展現執行計劃信息,並展現被選中的執行計劃的執行狀況信息,還展現備選的執行計劃的執行狀況信息;
第三步 解讀explain結果
queryPlanner(執行計劃描述)
winningPlan(被選中的執行計劃)
stage(可選項:COLLSCAN 沒有走索引;IXSCAN使用了索引)
rejectedPlans(候選的執行計劃)
executionStats(執行狀況描述)
nReturned (返回的文檔個數)
executionTimeMillis(執行時間ms)
totalKeysExamined (檢查的索引鍵值個數)
totalDocsExamined (檢查的文檔個數)
優化目標 Tips:
1. 根據需求創建索引
2. 每一個查詢都要使用索引以提升查詢效率, winningPlan. stage 必須爲IXSCAN ;
3. 追求totalDocsExamined = nReturned
4. mongodb 的索引注意事項?
1. 索引頗有用,可是它也是有成本的——它佔內存,讓寫入變慢;
2. mongoDB一般在一次查詢裏使用一個索引,因此多個字段的查詢或者排序須要複合索引才能更加高效;
3. 複合索引的順序很是重要
4. 在生成環境構建索引每每開銷很大,時間也不能夠接受,在數據量龐大以前儘可能進行查詢優化和構建索引;
5. 避免昂貴的查詢,使用查詢分析器記錄那些開銷很大的查詢便於問題排查;
6. 經過減小掃描文檔數量來優化查詢,使用explai對開銷大的查詢進行分析並優化;
7. 索引是用來查詢小範圍數據的,不適合使用索引的狀況:
每次查詢都須要返回大部分數據的文檔,避免使用索引
寫比讀多
5. mongodb 是怎麼實現高可用?
1. 結合項目經驗,說下 redis 應用場景
緩存:合理使用緩存加快數據訪問速度,下降後端數據源壓力
排行榜:按照熱度排名,按照發布時間排行,主要用到列表和有序集合
計數器應用:視頻網站播放數,網站瀏覽數,使用redis計數
社交網絡:贊、踩、粉絲、下拉刷新
消息隊列:發佈和訂閱
2. redis 支持數據類型?各有什麼特色?
String(字符串)
string類型是二進制安全的。意思是redis的string能夠包含任何數據。好比jpg圖片或者序列化的對象 。string類型是Redis最基本的數據類型,一個redis中字符串value最多能夠是512M
Hash(哈希)
Redis hash 是一個鍵值對集合。Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。相似Java裏面的Map<String,Object>
List(列表)
Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素導列表的頭部(左邊)或者尾部(右邊),它的底層實際是個鏈表
Set(集合)
Redis的Set是string類型的無序集合。它是經過HashTable實現實現的,
zset(sorted set:有序集合)
Redis zset 和 set 同樣也是string類型元素的集合,且不容許重複的成員。不一樣的是每一個元素都會關聯一個double類型的分數。redis正是經過分數來爲集合中的成員進行從小到大的排序。zset的成員是惟一的,但分數(score)卻能夠重複。
3. 有什麼持久化策略?各有什麼特色
策略:支持RDB和AOF兩種持久化機制,能夠避免因進程退出形成數據丟失,特色以下:
RDB持久化把當前進程數據生成快照(.rdb)文件保存到硬盤的過程,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。 優勢在於使用單獨子進程來進行持久化,主進程不會進行任何IO操做,保證了redis的高性能;缺點在於RDB是間隔一段時間進行持久化,若是持久化之間redis發生故障,會發生數據丟失。因此這種方式更適合數據要求不嚴謹的時候;有手動觸發和自動觸發,手動觸發有save和
bgsave兩命令 ;
save命令:阻塞當前Redis,直到RDB持久化過程完成爲止,若內存實例比較大會形成長時間阻塞,線上環境不建議用它
bgsave命令:redis進程執行fork操做建立子線程,由子線程完成持久化,阻塞時間很短(微秒級),是save的優化,在執行redis-cli shutdown關閉redis服x務時,如
果沒有開啓AOF持久化,自動執行bgsave; 顯然bgsave是對save的優化
AOF:針對RDB不適合實時持久化,redis提供了AOF持久化方式來解決,將「操做 +數據」以格式化指令的方式追加到操做日誌文件的尾部,在append操做返回後(已經寫入到文件或者即將寫入),才進行實際的數據變動,「日誌文件」保存了歷史全部的操做過程;當server須要數據恢復時,能夠直接replay此日誌文件,便可還原全部的操做過程
開啓:redis.conf設置:appendonly yes (默認不開啓,爲no)
默認文件名:appendfilename "appendonly.aof"
5. 介紹下哨兵機制
redis sentinel是一個分佈式架構,其中包含了若干個sentinal節點和Redis節點,每一個sentinel節點會對數據節點和sentinel節點進行監控,當它發現節點不可達是,會對節點作下線標識。若是大部分sentinal節點認爲主節點不可達,sentinal節點之間會進行「協商」 ,選舉出來一個sentinal節點完成故障轉義,並同時把這個故障通知到應用方;
6. 介紹 redis 集羣方案?以及其原理
RedisCluster是redis的分佈式解決方案,在3.0版本後推出的方案,有效地解決了Redis分佈式的需求,當遇到單機內存、併發等瓶頸時,可以使用此方案來解決這些問題,一個 redis 集羣包含 16384 個哈希槽(hash slot),數據庫中的每一個數據都屬於這16384個哈希槽中的一個。集羣使用公式(CRC16[key]&16383)函數來計算鍵 key屬於哪一個槽。集羣中的每個節點負責處理一部分哈希槽。
7. redis 能作讀寫分離嗎?同步策略是怎麼實現的?
redis提供了主從複製和哨兵機制來提升redis服務的健壯性和高可用,可是從嚴格意義上來說,redis並無實現讀寫分離,主從複製架構中,主節點用於響應讀寫請求,從節點用於數據備份,若是須要實現讀從從節點讀,應用須要對客戶端進行改造;但在真實場景下通常不須要作此方案,讀寫分離主要應用在磁盤IO比較大的場景,而redis是緩存級別的
同步策略: redis 2.8版本以上使用psync命令完成同步,過程分「全量」與「部分」複製 a) 全量複製:通常用於初次複製場景(第一次創建SLAVE後全量) b) 部分複製:網絡出現問題,從節佔再次連主時,主節點補發缺乏的數據,每次數據增長同步