1.什么樣的場(chǎng)景會(huì)產(chǎn)生數(shù)據(jù)庫(kù)死鎖税弃,如何解決?
第一條:事務(wù)之間對(duì)資源訪問順序的交替
簡(jiǎn)單說就是凑队,
用戶1訪問A表则果,用戶2訪問B表。
然后1還要訪問B漩氨,2還要訪問A西壮。
但是1鎖住了A,2鎖住了B叫惊。
死鎖了茸时。
解決辦法:
調(diào)整程序的邏輯,一般操作多張表的話赋访,避免這樣交替順序的表操作可都。
第二條:并發(fā)修改同一記錄
用戶1和用戶2都要對(duì)一條記錄修改。
先讀取記錄蚓耽,獲取共享鎖渠牲。這時(shí)候兩個(gè)事務(wù)獲得了共享模式鎖。
然后試圖修改步悠,共享鎖要轉(zhuǎn)換為排他鎖签杈,
因?yàn)橐粋€(gè)事務(wù)的排他鎖和其他事務(wù)的共享鎖是不兼容的。即:要等待其他事務(wù)釋放共享鎖。
所以這時(shí)候發(fā)生鎖等待答姥,兩個(gè)事務(wù)都在等待另一個(gè)事務(wù)釋放共享鎖铣除,發(fā)生死鎖。
解決辦法:
a.樂觀鎖鹦付。
b.悲觀鎖尚粘。
c.sqlserver的更新鎖。
第三條:索引不當(dāng)導(dǎo)致全表掃描
事務(wù)在執(zhí)行一條不滿足條件的語(yǔ)句敲长,執(zhí)行全表掃描郎嫁,行級(jí)鎖上升為表級(jí)鎖。
多個(gè)事務(wù)執(zhí)行后祈噪,容易發(fā)生阻塞和死鎖泽铛。
數(shù)據(jù)量大,索引少的時(shí)候辑鲤。應(yīng)用系統(tǒng)變慢盔腔,阻塞發(fā)生死鎖。
sql語(yǔ)句不要使用太復(fù)雜的關(guān)聯(lián)多表查詢月褥,建立相關(guān)索引優(yōu)化弛随。
2.sql如何優(yōu)化
第一條:還是索引問題
索引建立時(shí)需要注意的地方
避免對(duì)索引字段(
計(jì)算
使用not,<>,!=
使用is null 和 is not null
出現(xiàn)數(shù)據(jù)類型轉(zhuǎn)化
使用函數(shù)
使用空值(控制可以用默認(rèn)值代替)
)
說簡(jiǎn)單點(diǎn)就是索引要建的合適,如果索引是數(shù)字(日期也是)的話吓坚,不要以字符格式聲明數(shù)字,因?yàn)闀?huì)使索引無效灯荧,產(chǎn)生全表掃描礁击。
order by 和 where 后面經(jīng)常寫的字段,如果也滿足規(guī)則逗载,最好索引哆窿。
并不是所有索引對(duì)查詢都有效,如果一個(gè)索引有大量重復(fù)數(shù)據(jù)時(shí)厉斟,sql可能不會(huì)利用索引挚躯,比如說性別。
索引不是說越多越好擦秽,索引提高了select效率码荔,降低了insert和update效率。因?yàn)閕nsert和update可能重建索引感挥。一個(gè)表索引最好不要超過6個(gè)缩搅。
能使用數(shù)字類型字段就不要用字符型。字符型會(huì)一個(gè)一個(gè)字符比較触幼,數(shù)字型只需要比較一次硼瓣。
第二條:多個(gè)update就寫成一個(gè)好了
第三條:用 exist 和 not exist 替換 in 和 not in,
如果是連續(xù)數(shù)字也可以用between
第四條:不要寫select * 置谦,要把字段寫全了
第五條:distinct堂鲤,union亿傅,minus,intersect瘟栖,order by
需要啟動(dòng)sql引擎葵擎,distinct需要一次排序,其他兩次慢宗。
第六條:在一種情況下可以避免使用or坪蚁,在or的字段是索引時(shí),寧愿查詢兩次镜沽。
例子:
select id from t where num=10 or num=20;
可以這樣查詢
select id from t where num=10;
select id from t where num=20;
第七條:海量數(shù)據(jù)查詢避免格式轉(zhuǎn)換
第八條:盡可能使用更小的數(shù)據(jù)類型敏晤,比如mediumint 代替 int
第九條:盡可能使用enum
————————————————
3.oracle 和 mysql 使用分頁(yè)
oracle:
oracle使用rownum實(shí)現(xiàn)。
rownum沒有>,>= 因?yàn)閛racle行式數(shù)據(jù)庫(kù)
所以缅茉,如果分頁(yè)的數(shù)據(jù)不需要排序可以直接
select * from (
select rownum rn,a.* from student a where rownum <= 8
) where rn >= 5
如果需要先排序就是這樣
select * from (
select rownum rn,a.* from (
select b.* from student b order by studentId asc
) a where rownum <= 8
) where rn >= 5
mysql:
mysql使用limit實(shí)現(xiàn)嘴脾。
select * from student limit n,m;
n:(currentPage-1)*pageSize
m:pageSize
——————————————————————
4.唯一索引能否插入空
mysql:
唯一索引允許插入空,
創(chuàng)建唯一索引sql舉例:
CREATE UNIQUE INDEX index_name
ON table_name(index_column_1,index_column_2,...);
ALTER TABLE table_name
ADD CONSTRAINT constraint_name UNIQUE KEY(column_1,column_2,...);
CREATE TABLE table_name(
...
UNIQUE KEY(index_column_,index_column_2,...)
);
5.SQL怎樣判斷字段是否為空
sqlserver用isnull函數(shù)
oracle用nvl函數(shù)
mysql用ifnull函數(shù)或者coalesce函數(shù)
(如果字段是null就轉(zhuǎn)化成字段后面的內(nèi)容)
select * from student where colesce(student_name,'')<>'';