1.對查詢進(jìn)行優(yōu)化,要盡量避免全表掃描霹娄,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
2.應(yīng)盡量避免在 where 子句中對字段進(jìn)行 null 值判斷犬耻,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描踩晶,如:select id from t where num is null
最好不要給數(shù)據(jù)庫留NULL渡蜻,盡可能的使用 NOT NULL填充數(shù)據(jù)庫,備注、描述排苍、評論之類的可以設(shè)置為 NULL,其他的淘衙,最好不要使用NULL。
不要以為 NULL 不需要空間腻暮,比如:char(100) 型,在字段建立時哭靖,空間就固定了, 不管是否插入值(NULL也包含在內(nèi))款青,都是占用 100個字符的空間的霍狰,如果是varchar這樣的變長字段抡草, null 不占用空間蔗坯。
可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值宾濒,然后這樣查詢:select id from t where num = 0
3.應(yīng)盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描绘梦。
4.應(yīng)盡量避免在 where 子句中使用 or 來連接條件,如果一個字段有索引卸奉,一個字段沒有索引,將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描榄棵,如:select id from t where num=10 or Name = 'admin'
可以這樣查詢:select id from t where num = 10?? union???? select id from t where Name = 'admin'
應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描疹鳄。如:select id from t where num/2 = 100???? 應(yīng)改為:select id from t where num = 100*2
5.應(yīng)盡量避免在where子句中對字段進(jìn)行函數(shù)操作拧略,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描瘪弓。如:select id from t where substring(name,1,3) = ’abc’? ? ? -–name以abc開頭的id
select id from t where datediff(day,createdate,’2005-11-30′) = 0? ? -–‘2005-11-30’? ? --生成的id?? 應(yīng)改為:
select id from t where name like 'abc%'
select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
6.select count(*) from table;這樣不帶任何條件的count會引起全表掃描,并且沒有任何業(yè)務(wù)意義弛随,是一定要杜絕的,可以用count(1)代替
7.盡可能的使用 varchar/nvarchar 代替 char/nchar 舀透,因?yàn)槭紫茸冮L字段存儲空間小,可以節(jié)省存儲空間决左,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些佛猛。
8.任何地方都不要使用 select * from t ,用具體的字段列表代替“*”继找,不要返回用不到的任何字段。
9.任何地方都不要使用 select * from t 婴渡,用具體的字段列表代替“*”,不要返回用不到的任何字段边臼。
1.Innerjoin和左連接哄尔,右連接柠并,子查詢
A.? ? inner join內(nèi)連接也叫等值連接是岭接,left/rightjoin是外連接臼予。
SELECT A.id,A.name,B.id,B.name FROM A LEFT JOIN B ON A.id =B.id;
SELECT A.id,A.name,B.id,B.name FROM A RIGHT JOIN ON B A.id= B.id;
SELECT A.id,A.name,B.id,B.name FROM A INNER JOIN ON A.id =B.id;
經(jīng)過來之多方面的證實(shí)inner join性能比較快,因?yàn)閕nner join是等值連接粘拾,或許返回的行數(shù)比較少。但是我們要記得有些語句隱形的用到了等值連接半哟,如:
SELECT A.id,A.name,B.id,B.name FROM A,B WHERE A.id = B.id;
推薦:能用inner join連接盡量使用inner join連接
10.利用limit 1取得唯一行
A.有時要查詢一張表時,你要知道需要看一行寓涨,你可能去查詢一條獨(dú)特的記錄盯串。你可以使用limit 1.來終止數(shù)據(jù)庫引擎繼續(xù)掃描整個表或者索引,如:
Select * from A? where namelike ‘%xxx’ limit 1;
這樣只要查詢符合like ‘%xxx’的記錄戒良,那么引擎就不會繼續(xù)掃描表或者索引了。
11.不要在列上進(jìn)行運(yùn)算
A. 如下面:select * fromusers where YEAR(adddate)<2007;將在每個行進(jìn)行運(yùn)算,這些導(dǎo)致索引失效進(jìn)行全表掃描河泳,因此我們可以改成:
Select * from users where adddate<’2007-01-01’;
12.盡量不要使用NOT IN和<>操作
A. NOT IN和<>操作都不會使用索引,而是將會進(jìn)行全表掃描年栓。NOT IN可以NOT EXISTS代替,id<>3則可以使用id>3 or id <3;如果NOT EXISTS是子查詢某抓,還可以盡量轉(zhuǎn)化為外連接或者等值連接,要看具體sql的業(yè)務(wù)邏輯否副。
13.使用批量插入節(jié)省交互(最好是使用存儲過程)
A. 盡量使用insert intousers(username,password) values(‘test1’,’pass1’), (‘test2’,’pass2’), (‘test3’,’pass3’);
14、sql盡量保持全大寫的書寫形式备禀。筆者第一份工作接觸的就是oracle數(shù)據(jù)庫,oracle在執(zhí)行時會默認(rèn)將sql轉(zhuǎn)換為大寫曲尸,雖然我們知道sql是不區(qū)分大小寫的赋续,但是保持統(tǒng)一的風(fēng)格以及讓oracle免去這一次轉(zhuǎn)換也是很有意義的队腐;