mysql 索引失效有以下幾種情況
1详民,or 語(yǔ)句,如果要在or語(yǔ)句中使用索引陌兑,那么所有條件都必須使用索引沈跨,建議盡量少用or語(yǔ)句
2,like 前綴兔综,類(lèi)似語(yǔ)句 ?like '%aa
3,使用索引效率比不使用更低饿凛,比如TYPE
4.索引不存空值狞玛,所以 ?is null 條件語(yǔ)句不使用
5,多列索引涧窒,有預(yù)判心肪,其他索引列失效
6,索引列是字符串杀狡,沒(méi)用使用引號(hào)擴(kuò)起
mysql ?兩種索引方法蒙畴,一種是B-Tree索引,一種是Hash索引
使用場(chǎng)景為值的差異性較大呜象,且以等值比較為條件膳凝,比如> = <用hash效率高
差異性較差,且以范圍為條件恭陡,建議使用B-tree方法蹬音,以為B-Tree支持范圍查找
mysql 對(duì)數(shù)據(jù)的存取和操作系統(tǒng)一樣,通過(guò)鎖控制事務(wù)的有序安全的進(jìn)行休玩,mysql的鎖分為排他所即x鎖和共享鎖即s鎖著淆,當(dāng)數(shù)據(jù)加上排他鎖之后,其他事務(wù)不能對(duì)它進(jìn)行查看修改拴疤,加了共享鎖永部,其他事務(wù)可以進(jìn)行查看,但不能修改呐矾!
死鎖有三種情況
第一種情況苔埋,用戶(hù)1訪問(wèn)表A(鎖住A表),然后訪問(wèn)表B蜒犯,用戶(hù)2组橄,訪問(wèn)表B(鎖住B),然后訪問(wèn)表A,這樣用戶(hù)1等待用戶(hù)2釋放表B上的鎖,用戶(hù)2等待用戶(hù)1釋放表A上的鎖罚随!
解決方法:主要由于邏輯程序bug產(chǎn)生玉工,在事務(wù)的執(zhí)行順序上,如果有多個(gè)資源淘菩,保證代碼執(zhí)行資源順序的一致性遵班,比如事務(wù)A和事務(wù)B都是更新A表后然后執(zhí)行B表,那么都按這個(gè)順序執(zhí)行潮改,如操作A和B兩張表時(shí)费奸,總是按先A后B的順序處理, 必須同時(shí)鎖定兩個(gè)資源時(shí)进陡,要保證在任何時(shí)刻都應(yīng)該按照相同的順序來(lái)鎖定資源。
第二種情況微服,事務(wù)a查詢(xún)一條記錄趾疚,然后準(zhǔn)備更新這條記錄缨历,事務(wù)b進(jìn)行同樣的操作,但由于速度過(guò)快糙麦,事務(wù)a沒(méi)來(lái)來(lái)得及commit,那么事務(wù)a查詢(xún)獲得這條記錄的共享鎖辛孵,并且事務(wù)a準(zhǔn)備更新獲得排他鎖,此時(shí)b同樣獲得該條記錄的共享鎖赡磅,事務(wù)a等待事務(wù)b釋放鎖魄缚,進(jìn)行更新,同樣事務(wù)b等待事務(wù)a執(zhí)行完進(jìn)行更新焚廊,產(chǎn)生死鎖冶匹!場(chǎng)景如下,如果一個(gè)按鈕沒(méi)有失效設(shè)置咆瘟,用戶(hù)一直點(diǎn)嚼隘,就會(huì)出現(xiàn)上述情況
解決方法:1,按鈕點(diǎn)擊置灰
2袒餐,使用悲觀鎖飞蛹,select for update ?在查詢(xún)的時(shí)候就加排他鎖,那么事務(wù)b就不能進(jìn)行查詢(xún)獲得共享鎖
3.使用樂(lè)觀鎖灸眼,在每條數(shù)據(jù)加版本號(hào)version字段卧檐,對(duì)所讀操作的數(shù)據(jù)都不加鎖,事務(wù)a和事務(wù)b第一部查出相應(yīng)的版本號(hào)v焰宣,在更新前在把提交數(shù)據(jù)與數(shù)據(jù)庫(kù)版本比較霉囚,例如,update set where (v+1)>version,如果不大于認(rèn)為過(guò)期就不進(jìn)行更新了
第三種情況
1宛徊,如果使用一條update不滿足條件的sql語(yǔ)句佛嬉,那么行鎖變成了表鎖,比如索引失效情況闸天,用了is null ?或者type建立索引或者使用了like % 暖呕,或者的話where條件里面木有使用索引,那么就變成了全表掃描苞氮,update 語(yǔ)句也變成了表鎖湾揽,那么這樣的事務(wù)過(guò)多,造成死鎖或阻塞笼吟!
mysql innodb 行鎖升級(jí)為表鎖
innodb行鎖機(jī)制是對(duì)索引進(jìn)行加鎖库物,如果索引失效那么升級(jí)為表所
如果沒(méi)有使用索引,那么升級(jí)為表鎖
想要在已被其他事務(wù)用排他鎖占用的資源上面加鎖贷帮,即意向共享鎖戚揭,那么會(huì)行鎖會(huì)升級(jí)為表鎖
mysql ?如何鎖表
myisam引擎:select 進(jìn)行加共享鎖,update加排他鎖
innodb引擎:共享鎖(S):SELECT*FROM table_nameWHERE... LOCK INSHARE MODE
排他鎖(X):SELECT*FROMtable_nameWHERE...FOR UPDATE