索引哪些情況會失效?
- 查詢條件包含or,會導(dǎo)致索引失效(or前后都有索引,且都有序會生效?)。
- 隱式類型轉(zhuǎn)換。會導(dǎo)致索引失效,例如age字段類型是int,我們where age = “1”,這樣就會觸發(fā)隱式類型轉(zhuǎn)換。
- like通配符會導(dǎo)致索引失效。注意:"ABC%“會走range索引,”%ABC"索引才會失效。
- 聯(lián)合索引,查詢時(shí)的條件列不是聯(lián)合索引中的第一個(gè)列,索引失效。
- 對索引字段進(jìn)行函數(shù)運(yùn)算。
- 對索引列運(yùn)算(如,+、-、*、/),索引失效。
- 索引字段上使用(!= 或者 < >,not in)時(shí),會導(dǎo)致索引失效。
- 索引字段上使用is null, is not null,可能導(dǎo)致索引失效。
- 相join的兩個(gè)表的字符編碼不同,不能命中索引,會導(dǎo)致笛卡爾積的循環(huán)計(jì)算。
- mysql估計(jì)使用全表掃描要比使用索引快,則不使用索引。
索引不適合哪些場景?
- 數(shù)據(jù)量少的不適合加索引。
- 更新比較頻繁的也不適合加索引。
- 離散性低的字段不適合加索引(如性別)。
MySQL 遇到過死鎖問題嗎,你是如何解決的?
- 查看死鎖日志show engine innodb status;
- 找出死鎖Sql
- 分析sql加鎖情況
- 模擬死鎖案發(fā)
- 分析死鎖日志
- 分析死鎖結(jié)果
日常工作中你是怎么優(yōu)化SQL的?
- 加索引
- 避免返回不必要的數(shù)據(jù)
- 適當(dāng)分批量進(jìn)行
- 優(yōu)化sql結(jié)構(gòu)
分庫分表方案?
分表:
- 水平分表:以字段為依據(jù),按照一定策略(hash、range等),將一個(gè)表中的數(shù)據(jù)拆分到多個(gè)表中。
- 垂直分表:以字段為依據(jù),按照字段的活躍性,將表中字段拆到不同的表(主表和擴(kuò)展表)中。
分庫:
- 水平分庫:以字段為依據(jù),按照一定策略(hash、range等),將一個(gè)庫中的數(shù)據(jù)拆分到多個(gè)庫中。
- 垂直分庫:以表為依據(jù),按照業(yè)務(wù)歸屬不同,將不同的表拆分到不同的庫中。
分庫分表可能遇到的問題?
- 事務(wù)問題:需要用分布式事務(wù)
- 跨節(jié)點(diǎn)連表查詢問題:解決這一問題可以分兩次查詢實(shí)現(xiàn)
- 跨節(jié)點(diǎn)的count,order by,group by以及聚合函數(shù)問題:分別在各個(gè)節(jié)點(diǎn)上得到結(jié)果后在應(yīng)用程序端進(jìn)行合并。
- 數(shù)據(jù)遷移,容量規(guī)劃,擴(kuò)容等問題。
- ID問題:數(shù)據(jù)庫被切分后,不能再依賴數(shù)據(jù)庫自身的主鍵生成機(jī)制,最簡單可以考慮UUID。
- 跨分片的排序分頁問題
InnoDB與MyISAM的區(qū)別?
- InnoDB支持事務(wù),MyISAM不支持事務(wù)
- InnoDB支持外鍵,MyISAM不支持外鍵
- InnoDB 支持 MVCC(多版本并發(fā)控制),MyISAM 不支持
- select count(*) from table時(shí),MyISAM更快,因?yàn)樗幸粋€(gè)變量保存了整個(gè)表的總行數(shù),可以直接讀取,InnoDB就需要全表掃描。
- Innodb不支持全文索引,而MyISAM支持全文索引(5.7以后的InnoDB也支持全文索引)
- InnoDB支持表、行級鎖,而MyISAM支持表級鎖。
聚集索引與非聚集索引的區(qū)別?
- 一個(gè)表中只能擁有一個(gè)聚集索引,而非聚集索引一個(gè)表可以存在多個(gè)。
- 聚集索引中鍵值的邏輯順序決定了表中相應(yīng)行的物理順序;非聚集索引中索引的邏輯順序與磁盤上行的物理存儲順序不同。
- 索引是通過二叉樹的數(shù)據(jù)結(jié)構(gòu)來描述的,我們可以這么理解聚簇索引:索引的葉節(jié)點(diǎn)就是數(shù)據(jù)節(jié)點(diǎn)。而非聚簇索引的葉節(jié)點(diǎn)仍然是索引節(jié)點(diǎn),只不過有一個(gè)指針指向?qū)?yīng)的數(shù)據(jù)塊。
- 聚集索引:物理存儲按照索引排序;非聚集索引:物理存儲不按照索引排序;
limit 1000000 加載很慢的話,你是怎么解決的呢?
方案一:如果id是連續(xù)的,可以這樣,返回上次查詢的最大記錄(偏移量),再往下limit:
select id,name from employee where id>1000000 limit 10.
方案二:在業(yè)務(wù)允許的情況下限制頁數(shù):
建議跟業(yè)務(wù)討論,有沒有必要查這么后的分頁。因?yàn)榻^大多數(shù)用戶都不會往后翻太多頁。
方案三:order by + 索引(id為索引)
select id,name from employee order by id limit 1000000,10
方案四:利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多分頁場景。(先快速定位需要獲取的id段,然后再關(guān)聯(lián)):
SELECT a.* FROM employee a, (select id from employee where 條件 LIMIT 1000000,10 ) b where a.id=b.id
如何選擇合適的分布式主鍵方案呢?
雪花算法
Redis生成ID
利用zookeeper生成唯一ID
什么是事務(wù)的隔離性?
隔離性是指,多個(gè)用戶的并發(fā)事務(wù)訪問同一個(gè)數(shù)據(jù)庫時(shí),一個(gè)用戶的事務(wù)不應(yīng)該被其他用戶的事務(wù)干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。
事務(wù)的隔離級別有哪些?
讀未提交(Read Uncommitted)
讀提交(Read Committed, RC)
可重復(fù)讀(Repeated Read, RR)
串行化(Serializable)
InnoDB的四種事務(wù)的隔離級別,分別是怎么實(shí)現(xiàn)的?
InnoDB使用不同的鎖策略(Locking Strategy)來實(shí)現(xiàn)不同的隔離級別。
讀未提交(Read Uncommitted):
這種事務(wù)隔離級別下,select語句不加鎖。
此時(shí),可能讀取到不一致的數(shù)據(jù),即“讀臟”。這是并發(fā)最高,一致性最差的隔離級別。
串行化(Serializable):
這種事務(wù)的隔離級別下,所有select語句都會被隱式的轉(zhuǎn)化為select … in share mode。
這可能導(dǎo)致,如果有未提交的事務(wù)正在修改某些行,所有讀取這些行的select都會被阻塞住。
這是一致性最好的,但并發(fā)性最差的隔離級別。 在大數(shù)據(jù)量,高并發(fā)量的場景下,幾乎不會使用上述兩種隔離級別。
可重復(fù)讀(Repeated Read, RR):
這是InnoDB默認(rèn)的隔離級別,在RR下:
- 普通的select使用快照讀(snapshot read),這是一種不加鎖的一致性讀(Consistent Nonlocking Read),底層使用MVCC來實(shí)現(xiàn);
- 加鎖的select(select … in share mode / select … for update), update, delete等語句,它們的鎖,依賴于它們是否在唯一索引(unique index)上使用了唯一的查詢條件(unique search condition),或者范圍查詢條件(range-type search condition):
- 在唯一索引上使用唯一的查詢條件,會使用記錄鎖(record lock),而不會封鎖記錄之間的間隔,即不會使用間隙鎖(gap lock)與臨鍵鎖(next-key lock)。
- 范圍查詢條件,會使用間隙鎖與臨鍵鎖,鎖住索引記錄之間的范圍,避免范圍間插入記錄,以避免產(chǎn)生幻影行記錄,以及避免不可重復(fù)的讀
讀提交(Read Committed, RC):
這是互聯(lián)網(wǎng)最常用的隔離級別,在RC下:
- 普通讀是快照讀;
- 加鎖的select, update, delete等語句,除了在外鍵約束檢查(foreign-key constraint checking)以及重復(fù)鍵檢查(duplicate-key checking)時(shí)會封鎖區(qū)間,其他時(shí)刻都只使用記錄鎖;
此時(shí),其他事務(wù)的插入依然可以執(zhí)行,就可能導(dǎo)致,讀取到幻影記錄。
在高并發(fā)情況下,如何做到安全的修改同一行數(shù)據(jù)?
要安全的修改同一行數(shù)據(jù),就要保證一個(gè)線程在修改時(shí)其它線程無法更新這行記錄。一般有悲觀鎖和樂觀鎖兩種方案:
悲觀鎖:當(dāng)前線程要進(jìn)來修改數(shù)據(jù)時(shí),別的線程都得拒之門外~ 比如,可以使用select…for update
樂觀鎖:有線程過來,先放過去修改,如果看到別的線程沒修改過,就可以修改成功,如果別的線程修改過,就修改失敗或者重試。實(shí)現(xiàn)方式:樂觀鎖一般會使用版本號機(jī)制或CAS算法實(shí)現(xiàn)。
SQL優(yōu)化的一般步驟是什么,怎么看執(zhí)行計(jì)劃(explain),如何理解其中各個(gè)字段的含義?
- show status 命令了解各種 sql 的執(zhí)行頻率
- 通過慢查詢?nèi)罩径ㄎ荒切﹫?zhí)行效率較低的 sql 語句
- explain 分析低效 sql 的執(zhí)行計(jì)劃(這點(diǎn)非常重要,日常開發(fā)中用它分析Sql,會大大降低Sql導(dǎo)致的線上事故)
select for update有什么含義,會鎖表還是鎖行還是其他?
select查詢語句是不會加鎖的,但是select for update除了有查詢的作用外,還會加鎖,而且是悲觀鎖。
至于加了是行鎖還是表鎖,這就要看是不是用了索引/主鍵。 沒用索引/主鍵的話就是表鎖,否則就是是行鎖。
MySQL事務(wù)得四大特性以及實(shí)現(xiàn)原理?
原子性: 事務(wù)作為一個(gè)整體被執(zhí)行,包含在其中的對數(shù)據(jù)庫的操作要么全部被執(zhí)行,要么都不執(zhí)行。
一致性: 指在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)不會被破壞,假如A賬戶給B賬戶轉(zhuǎn)10塊錢,不管成功與否,A和B的總金額是不變的。
隔離性: 多個(gè)事務(wù)并發(fā)訪問時(shí),事務(wù)之間是相互隔離的,即一個(gè)事務(wù)不影響其它事務(wù)運(yùn)行效果。
持久性: 表示事務(wù)完成以后,該事務(wù)對數(shù)據(jù)庫所作的操作更改,將持久地保存在數(shù)據(jù)庫之中。
事務(wù)ACID特性的實(shí)現(xiàn)思想?
原子性:是使用 undo log來實(shí)現(xiàn)的,如果事務(wù)執(zhí)行過程中出錯(cuò)或者用戶執(zhí)行了rollback,系統(tǒng)通過undo log日志返回事務(wù)開始的狀態(tài)。
持久性:使用 redo log來實(shí)現(xiàn),只要redo log日志持久化了,當(dāng)系統(tǒng)崩潰,即可通過redo log把數(shù)據(jù)恢復(fù)。
隔離性:通過鎖以及MVCC,使事務(wù)相互隔離開。
一致性:通過回滾、恢復(fù),以及并發(fā)情況下的隔離性,從而實(shí)現(xiàn)一致性。
如果某個(gè)表有近千萬數(shù)據(jù),CRUD比較慢,如何優(yōu)化?
- 分庫分表,分表(水平分表,垂直分表)
- 優(yōu)化表結(jié)構(gòu)
- 索引優(yōu)化
如何寫sql能夠有效的使用到復(fù)合索引?
復(fù)合索引,也叫組合索引,用戶可以在多個(gè)列上建立索引,這種索引叫做復(fù)合索引。
當(dāng)我們創(chuàng)建一個(gè)組合索引的時(shí)候,如(k1,k2,k3),相當(dāng)于創(chuàng)建了(k1)、(k1,k2)和(k1,k2,k3)三個(gè)索引,這就是最左匹配原則。
復(fù)合索引,我們需要關(guān)注查詢Sql條件的順序,確保最左匹配原則有效,同時(shí)可以刪除不必要的冗余索引。
mysql中in 和exists的區(qū)別?
mysql優(yōu)化原則是小表驅(qū)動(dòng)大表,小的數(shù)據(jù)集驅(qū)動(dòng)大的數(shù)據(jù)集,從而讓性能更優(yōu)。主表數(shù)據(jù)量大適合用in,關(guān)聯(lián)表數(shù)據(jù)量大適合用exists。
數(shù)據(jù)庫自增主鍵可能遇到什么問題?
使用自增主鍵對數(shù)據(jù)庫做分庫分表,可能出現(xiàn)諸如主鍵重復(fù)等的問題。解決方案的話,簡單點(diǎn)的話可以考慮使用UUID, 自增主鍵會產(chǎn)生表鎖,從而引發(fā)問題 自增主鍵可能用完問題。
說一下大表查詢的優(yōu)化方案?
優(yōu)化shema、sql語句+索引
可以考慮加緩存
主從復(fù)制,讀寫分離
分庫分表
InnoDB引擎中的索引策略?
當(dāng)索引幫助存儲引擎快速查找到記錄帶來的好處大于其帶來的額外工作時(shí),索引才是有效的。對于非常小的表,大部分情況下簡單的全表掃描更高效,對于中到大型的表,索引就非常有效。
如何爭取的創(chuàng)建和使用縮影?
- 索引列不能是表達(dá)式的一部分,也不是函數(shù)的參數(shù)。
- 長字符串只索引左邊開始的部分字符。
- 選擇合適的索引的選擇性:select count(distinct left(city,6))/count(*) from skill.city_demo
- 盡量使用聯(lián)合索引
前綴索引缺點(diǎn)?
MySQL無法使用前綴索引做ORDER BY和GROUP BY,也無法使用前綴索引做覆蓋掃描。
聯(lián)合索引列選擇原則?
- 經(jīng)常用的列優(yōu)先【最左匹配原則】
- 選擇性(離散性)高的優(yōu)先【離散度高原則】
- 寬度小的列優(yōu)先【最少空間原則】
- 選擇合適的索引列順序
一條sql執(zhí)行過長的時(shí)間,你如何優(yōu)化,從哪些方面入手?
- 查看是否涉及多表和子查詢,優(yōu)化Sql結(jié)構(gòu),如去除冗余字段,是否可拆表等
- 優(yōu)化索引結(jié)構(gòu),看是否可以適當(dāng)添加索引
- 數(shù)量大的表,可以考慮進(jìn)行分離/分表(如交易流水表)
- 數(shù)據(jù)庫主從分離,讀寫分離
- explain分析sql語句,查看執(zhí)行計(jì)劃,優(yōu)化sql
- 查看mysql執(zhí)行日志,分析是否有其他方面的問題
Blob和text有什么區(qū)別?
Blob用于存儲二進(jìn)制數(shù)據(jù),而Text用于存儲大字符串。
Blob值被視為二進(jìn)制字符串(字節(jié)字符串),它們沒有字符集,并且排序和比較基于列值中的字節(jié)的數(shù)值。
text值被視為非二進(jìn)制字符串(字符字符串)。它們有一個(gè)字符集,并根據(jù)字符集的排序規(guī)則對值進(jìn)行排序和比較。
MySQL里記錄貨幣用什么字段類型比較好?
貨幣在數(shù)據(jù)庫中MySQL常用Decimal和Numric類型表示,這兩種類型被MySQL實(shí)現(xiàn)為同樣的類型。他們被用于保存與金錢有關(guān)的數(shù)據(jù)。
DECIMAL和NUMERIC值作為字符串存儲,而不是作為二進(jìn)制浮點(diǎn)數(shù),以便保存那些值的小數(shù)精度。
如何使用普通鎖保證一致性?
操作數(shù)據(jù)前加鎖,實(shí)施互斥,不允許其他的并發(fā)任務(wù)操作。
操作完成后釋放鎖,讓其他任務(wù)執(zhí)行,來保證一致性。
普通鎖存在什么問題?
簡單的鎖住太過粗暴,連“讀任務(wù)”也無法并行,任務(wù)執(zhí)行過程本質(zhì)上是串行的。
InnoDB有哪幾種鎖?
-
共享/排它鎖(Shared and Exclusive Locks):
- 共享鎖(Share Locks,記為S鎖),讀取數(shù)據(jù)時(shí)加S鎖
- 排他鎖(eXclusive Locks,記為X鎖),修改數(shù)據(jù)時(shí)加X鎖
共享鎖之間不互斥,讀讀可以并行。
排他鎖與任何鎖互斥,寫讀,寫寫都不可以并行。
共享鎖和排它鎖存在讀寫互斥,對并發(fā)度有較大的影響。
-
意向鎖(Intention Locks):
- 意向鎖,是一個(gè)表級別的鎖(table-level locking)。
- 意向鎖分為:
- 意向共享鎖(intention shared lock, IS),它預(yù)示著,事務(wù)有意向?qū)Ρ碇械哪承┬屑庸蚕鞸鎖
- 意向排它鎖(intention exclusive lock, IX),它預(yù)示著,事務(wù)有意向?qū)Ρ碇械哪承┬屑优潘黊鎖
- select … lock in share mode,要設(shè)置IS鎖;select … for update,要設(shè)置IX鎖;
- 意向鎖協(xié)議(intention locking protocol):
- 事務(wù)要獲得某些行的S鎖,必須先獲得表的IS鎖
- 事務(wù)要獲得某些行的X鎖,必須先獲得表的IX鎖
- 由于意向鎖僅僅表明意向,它是比較弱的鎖,意向鎖之間并不相互互斥,其兼容互斥表如下:
IS IX IS 兼容 兼容 IX 兼容 兼容 - 意向鎖會與共享鎖/排它鎖互斥,其兼容互斥表如下:
S X IS 兼容 互斥 IX 互斥 互斥 InnoDB支持多粒度鎖(multiple granularity locking),它允許行級鎖與表級鎖共存,實(shí)際應(yīng)用中,InnoDB使用的是意向鎖。
意向鎖是指,未來的某個(gè)時(shí)刻,事務(wù)可能要加共享/排它鎖了,先提前聲明一個(gè)意向。
意向鎖解決什么問題?
如果事務(wù) A 獲取了某一行的排它鎖,事務(wù) B 想要獲取表的鎖(共享或者排他鎖)。因?yàn)楣蚕礞i與排它鎖互斥,所以事務(wù) B 在試圖對表鎖的時(shí)候,必須保證:
- 當(dāng)前沒有其他事務(wù)持有表的排它鎖。
- 當(dāng)前沒有其他事務(wù)持有表中任意一行的排它鎖 。
為了檢測是否滿足第二個(gè)條件,事務(wù) B 必須去檢測表中的每一行是否存在排它鎖。這是一個(gè)效率很差的做法,但是有了意向鎖之后,事務(wù)A持有了表的意向排它鎖,就可得知事務(wù)A必然持有該表中某些數(shù)據(jù)行的排它鎖,而無需去檢測表中每一行是否存在排它鎖。
Hash索引和B+樹區(qū)別是什么?你在設(shè)計(jì)索引是怎么抉擇的?
B+樹可以進(jìn)行范圍查詢,Hash索引不能。
B+樹支持聯(lián)合索引的最左側(cè)原則,Hash索引不支持。
B+樹支持order by排序,Hash索引不支持。
Hash索引在等值查詢上比B+樹效率更高。
B+樹使用like 進(jìn)行模糊查詢的時(shí)候,like后面(比如%開頭)的話可以起到優(yōu)化的作用,Hash索引根本無法進(jìn)行模糊查詢。
mysql 的內(nèi)連接、左連接、右連接有什么區(qū)別?
Inner join 內(nèi)連接,在兩張表進(jìn)行連接查詢時(shí),只保留兩張表中完全匹配的結(jié)果集。
left join 在兩張表進(jìn)行連接查詢時(shí),會返回左表所有的行,即使在右表中沒有匹配的記錄。
right join 在兩張表進(jìn)行連接查詢時(shí),會返回右表所有的行,即使在左表中沒有匹配的記錄。
什么是內(nèi)連接、外連接、交叉連接、笛卡爾積呢?
內(nèi)連接(inner join):取得兩張表中滿足存在連接匹配關(guān)系的記錄。
外連接(outer join):取得兩張表中滿足存在連接匹配關(guān)系的記錄,以及某張表(或兩張表)中不滿足匹配關(guān)系的記錄。
交叉連接(cross join):顯示兩張表所有記錄一一對應(yīng),沒有匹配關(guān)系進(jìn)行篩選,也被稱為:笛卡爾積。
主從復(fù)制binlog格式有哪幾種?有什么區(qū)別?
-
STATEMENT:基于語句的日志記錄,把所有寫操作的sql語句寫入 binlog (默認(rèn))
-
優(yōu)點(diǎn):
成熟的技術(shù)。
更少的數(shù)據(jù)寫入日志文件。當(dāng)更新或刪除影響許多行時(shí),這將導(dǎo)致日志文件所需的存儲空間大大減少。這也意味著從備份中獲取和還原可以更快地完成。
日志文件包含所有進(jìn)行了任何更改的語句,因此它們可用于審核數(shù)據(jù)庫。 -
缺點(diǎn):
有很多函數(shù)不能復(fù)制,例如now()、random()、uuid()等
-
優(yōu)點(diǎn):
-
ROW:基于行的日志記錄,把每一行的改變寫入binlog,假設(shè)一條sql語句影響100萬行,從節(jié)點(diǎn)需要執(zhí)行100萬次,效率低。
- 優(yōu)點(diǎn):可以復(fù)制所有更改,這是最安全的復(fù)制形式
- 缺點(diǎn):如果該SQL語句更改了許多行,則基于行的復(fù)制可能會向二進(jìn)制日志中寫入更多的數(shù)據(jù)。即使對于回滾的語句也是如此。這也意味著制作和還原備份可能需要更多時(shí)間。此外,二進(jìn)制日志被鎖定更長的時(shí)間以寫入數(shù)據(jù),這可能會導(dǎo)致并發(fā)問題。
MIXED:混合模式,如果 sql 里有函數(shù),自動(dòng)切換到 ROW 模式,如果 sql 里沒有會造成主從復(fù)制不一致的函數(shù),那么就使用STATEMENT模式。(存在問題:解決不了系統(tǒng)變量問題,例如@@host name,主從的主機(jī)名不一致)
索引有哪些優(yōu)缺點(diǎn)?
優(yōu)點(diǎn):
唯一索引可以保證數(shù)據(jù)庫表中每一行的數(shù)據(jù)的唯一性
索引可以加快數(shù)據(jù)查詢速度,減少查詢時(shí)間
缺點(diǎn):
- 創(chuàng)建索引和維護(hù)索引要耗費(fèi)時(shí)間
- 索引需要占物理空間,除了數(shù)據(jù)表占用數(shù)據(jù)空間之外,每一個(gè)索引還要占用一定的物理空間
- 以表中的數(shù)據(jù)進(jìn)行增、刪、改的時(shí)候,索引也要?jiǎng)討B(tài)的維護(hù)。
索引有哪幾種類型?
主鍵索引: 數(shù)據(jù)列不允許重復(fù),不允許為NULL,一個(gè)表只能有一個(gè)主鍵。
唯一索引: 數(shù)據(jù)列不允許重復(fù),允許為NULL值,一個(gè)表允許多個(gè)列創(chuàng)建唯一索引。
普通索引: 基本的索引類型,沒有唯一性的限制,允許為NULL值。
全文索引:是目前搜索引擎使用的一種關(guān)鍵技術(shù),對文本的內(nèi)容進(jìn)行分詞、搜索。
覆蓋索引:查詢列要被所建的索引覆蓋,不必讀取數(shù)據(jù)行
組合索引:多列值組成一個(gè)索引,用于組合搜索,效率大于索引合并
創(chuàng)建索引的三種方式?
在執(zhí)行CREATE TABLE時(shí)創(chuàng)建索引
使用ALTER TABLE命令添加索引
使用CREATE INDEX命令創(chuàng)建
百萬級別或以上的數(shù)據(jù),你是如何刪除的?
- 我們想要?jiǎng)h除百萬數(shù)據(jù)的時(shí)候可以先刪除索引
- 然后批量刪除其中無用數(shù)據(jù)
- 刪除完成后重新創(chuàng)建索引
組合索引是什么?為什么需要注意組合索引中的順序?
組合索引,用戶可以在多個(gè)列上建立索引,這種索引叫做組合索引。 因?yàn)镮nnoDB引擎中的索引策略的最左原則,所以需要注意組合索引中的順序。
什么是死鎖?怎么解決?
死鎖:
死鎖是指兩個(gè)或多個(gè)事務(wù)在同一資源上相互占用,并請求鎖定對方的資源,從而導(dǎo)致惡性循環(huán)的現(xiàn)象。
死鎖有四個(gè)必要條件:互斥條件,請求和保持條件,環(huán)路等待條件,不剝奪條件。
解決:
- 如果不同程序會并發(fā)存取多個(gè)表,盡量約定以相同的順序訪問表,可以大大降低死鎖機(jī)會。
- 在同一個(gè)事務(wù)中,盡可能做到一次鎖定所需要的所有資源,減少死鎖產(chǎn)生概率。
- 對于非常容易產(chǎn)生死鎖的業(yè)務(wù)部分,可以嘗試使用升級鎖定顆粒度,通過表級鎖定來減少死鎖產(chǎn)生的概率。
- 如果業(yè)務(wù)處理不好可以用分布式事務(wù)鎖或者使用樂觀鎖。
MySQL鎖介紹?
從并發(fā)的角度:
共享鎖/排他鎖
意象共享鎖/意象排他鎖
從一致性鎖定讀的角度:
行鎖/表鎖
間隙鎖/臨建鎖
左前綴匹配規(guī)則?
當(dāng)使用聯(lián)合索引時(shí),索引使用滿足左前綴規(guī)則。
例子:當(dāng)對字段A、B、C創(chuàng)建聯(lián)合索引時(shí),相當(dāng)于創(chuàng)建了A索引,A、B索引和A、B、C三個(gè)索引。
-
順序條件都會走索引:
- where A = 'a'
- where A = 'a' and B = 'b'
- where A = 'a' and B = 'b' and C = 'c'
-
從哪兒缺失從哪兒停止走索引:
- where A = 'a' and C = 'c' A走索引,C不走索引
- where C = 'c' 不走索引
- where B = 'b' and C = 'c' 不走索引
-
亂序條件會走索引:
- where B = 'b' and A = 'a' and C = 'c' 由于優(yōu)化器優(yōu)化,依然會走A、B、C索引
-
模糊查詢根據(jù)條件走索引:
- where A like 'a%' 走index或者range索引
- where A like '%a' 不走索引
- where A like '%a%' 不走索引
- where A = 'a' and b like 'b%' A走索引,b走范圍或者index索引
范圍查詢走索引:
where A = 'a' and B > 1 order by C A走索引,b走范圍索引,C不走索引,會導(dǎo)致文件排序。此時(shí)可以優(yōu)化成 A、C索引,這樣能走A、C索引,避免文件排序。