眾所周知,sql從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)的方式主要有通過(guò)索引掃描和全表掃描兩種方式獲取目標(biāo)數(shù)據(jù)六敬;當(dāng)數(shù)據(jù)量不大的時(shí)候诡右,兩者在效率上可能沒(méi)有區(qū)別安岂,但是當(dāng)數(shù)據(jù)量達(dá)到一定規(guī)模的時(shí)候,索引掃描明顯比全表掃描的效率高出很多帆吻; 在此也并不說(shuō)建立索引就是萬(wàn)能的域那,過(guò)多的索引浪費(fèi)存儲(chǔ)空間,加大了數(shù)據(jù)之間結(jié)構(gòu)的復(fù)雜性猜煮,降低了插入次员,更新的效率;因此要根據(jù)實(shí)際應(yīng)用場(chǎng)景選擇合適的方式友瘤,話不多說(shuō)翠肘,下面總結(jié)的幾條經(jīng)驗(yàn)如下:
盡量少使用select * from table; 因?yàn)檫@會(huì)導(dǎo)致掃描全表辫秧;
避免在where語(yǔ)句中對(duì)字段值為null的進(jìn)行判斷束倍,可設(shè)置默認(rèn)值0代替null;這樣會(huì)導(dǎo)致查詢放棄索引掃描而走全表掃描盟戏;
盡量對(duì)where 和order by绪妹,group by 設(shè)計(jì)的列建立索引;
慎用not in 和 in柿究,會(huì)導(dǎo)致全表索引邮旷;
在where語(yǔ)句中盡量少出現(xiàn) != < >;
對(duì)于where語(yǔ)句中條件為連續(xù)數(shù)據(jù)時(shí)蝇摸,使用between婶肩,而不是in ;
將 select fields from table where name='**' or name ="&&" 改為
select fields from table where name='**' union all select fields from table where name='&&'
對(duì)于select? fields from table where name like '%dfb%' 改為使用建立全文索引貌夕;
在where中條件盡量保持明確律歼,避免使用代表式或是函數(shù)作為條件;
select fields from table where age/2=5啡专;
select fields from table where substring(name,1,3) ='bcd' # 以bcd開(kāi)頭的name
用exists 代替 in险毁;
select fields from table_a where exists(select fields from table_b where num=table_a.num)
盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型,這會(huì)降低查詢和連接的性能畔况,并會(huì)增加存儲(chǔ)開(kāi)銷鲸鹦。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符,而對(duì)于數(shù)字型而言只需要比較一次就夠跷跪;
如果使用到了臨時(shí)表馋嗜,在存儲(chǔ)過(guò)程的最后務(wù)必將所有的臨時(shí)表顯式刪除,先 truncate table 域庇,然后 drop table 嵌戈,這樣可以避免系統(tǒng)表的較長(zhǎng)時(shí)間鎖定
盡量保持一張表字段數(shù)量不要太多,可以考慮分表存儲(chǔ)數(shù)據(jù)听皿,然后通過(guò)join獲取數(shù)據(jù)熟呛;
在所有的存儲(chǔ)過(guò)程和觸發(fā)器的開(kāi)始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時(shí)設(shè)置 SET NOCOUNT OFF 尉姨。無(wú)需在執(zhí)行存儲(chǔ)過(guò)程和觸發(fā)器的每個(gè)語(yǔ)句后向客戶端發(fā)送 DONE_IN_PROC 消息庵朝。
避免一次性向客戶端返回大量數(shù)據(jù);
并不是所有索引對(duì)查詢都有效又厉,SQL是根據(jù)表中數(shù)據(jù)來(lái)進(jìn)行查詢優(yōu)化的九府,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時(shí),SQL查詢可能不會(huì)去利用索引覆致;
Ps: 建立全文索引的方式:
首先mysql的引擎innoDB是不支持使用全文索引的侄旬,所以如果是innoDB,先修改引擎類型:
alter table table_name engine=MyISAM
其次建立索引:alter table table_name add fulltext index(字段1煌妈,字段2, ....)
最后查詢:select * from table_name where match(字段1儡羔,字段2,....) against(字段名)
????match ... against ...:相關(guān)性排序,由高到低璧诵,match(字段順序應(yīng)與 fulltext中相同汰蜘,不然會(huì)報(bào)錯(cuò))?
原文鏈接: https://www.onexing.cn