小編給大家分享一下MySQL進(jìn)行sql優(yōu)化的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)公司長期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為南鄭企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),南鄭網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
mysql進(jìn)行sql優(yōu)化的方法:1、避免全表掃描,在where及order by涉及的列上建立索引;2、在where子句中避免對(duì)字段進(jìn)行null值判斷,避免使用“!=”或“<>”操作符,避免使用or來連接條件;3、慎用in和not in。
MySQL中的SQL的常見優(yōu)化策略
1 避免全表掃描
對(duì)查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
2 避免判斷null值
應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:
select id from t where num is null
可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
3 避免不等值判斷
應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則引擎將放棄使用索引而進(jìn)行全表掃描。
4 避免使用or邏輯
應(yīng)盡量避免在 where 子句中使用 or 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10 union all select id from t where num=20
5 慎用in和not in邏輯
in 和 not in 也要慎用,否則會(huì)導(dǎo)致全表掃描,如:
select id from t1 where num in(select id from t2 where id > 10)
此時(shí)外層查詢會(huì)全表掃描,不使用索引??梢孕薷臑椋?br/>select id from t1,(select id from t1 where id > 10)t2 where t1.id = t2.id
此時(shí)索引被使用,可以明顯提升查詢效率。
6 注意模糊查詢
下面的查詢也將導(dǎo)致全表掃描:
select id from t where name like '%abc%'
模糊查詢?nèi)绻潜匾獥l件時(shí),可以使用select id from t where name like 'abc%'來實(shí)現(xiàn)模糊查詢,此時(shí)索引將被使用。如果頭匹配是必要邏輯,建議使用全文搜索引擎(Elastic search、Lucene、Solr等)。
7 避免查詢條件中字段計(jì)算
應(yīng)盡量避免在 where 子句中對(duì)字段進(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
8 避免查詢條件中對(duì)字段進(jìn)行函數(shù)操作
應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:
select id from t where substring(name,1,3)='abc'--name以abc開頭的id
應(yīng)改為:
select id from t where name like 'abc%'
9 WHERE子句“=”左邊注意點(diǎn)
不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無法正確使用索引。
10 組合索引使用
在使用索引字段作為條件時(shí),如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引,否則該索引將不會(huì)被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
11 不要定義無異議的查詢
不要寫一些沒有意義的查詢,如需要生成一個(gè)空表結(jié)構(gòu):
select col1,col2 into #t from t where 1=0
這類代碼不會(huì)返回任何結(jié)果集,但是會(huì)消耗系統(tǒng)資源的,應(yīng)改成這樣:
create table #t(...)
12 exists
很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇:
select num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
13 索引也可能失效
并不是所有索引對(duì)查詢都有效,SQL是根據(jù)表中數(shù)據(jù)來進(jìn)行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時(shí),SQL查詢可能不會(huì)去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對(duì)查詢效率起不了作用。
14 表格字段類型選擇
盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型,這會(huì)降低查詢和連接的性能,并會(huì)增加存儲(chǔ)開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符,而對(duì)于數(shù)字型而言只需要比較一次就夠了。
盡可能的使用 varchar 代替 char ,因?yàn)槭紫瓤勺冮L度字段存儲(chǔ)空間小,可以節(jié)省存儲(chǔ)空間,其次對(duì)于查詢來說,在一個(gè)相對(duì)較小的字段內(nèi)搜索效率顯然要高些。
15 查詢語法中的字段
任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
16 索引無關(guān)優(yōu)化
不使用*、盡量不使用union,union all等關(guān)鍵字、盡量不使用or關(guān)鍵字、盡量使用等值判斷。
表連接建議不超過5個(gè)。如果超過5個(gè),則考慮表格的設(shè)計(jì)。(互聯(lián)網(wǎng)應(yīng)用中)
表連接方式使用外聯(lián)優(yōu)于內(nèi)聯(lián)。
外連接有基礎(chǔ)數(shù)據(jù)存在。如:A left join B,基礎(chǔ)數(shù)據(jù)是A。
A inner join B,沒有基礎(chǔ)數(shù)據(jù)的,先使用笛卡爾積完成全連接,在根據(jù)連接條件得到內(nèi)連接結(jié)果集。
大數(shù)據(jù)量級(jí)的表格做分頁查詢時(shí),如果頁碼數(shù)量過大,則使用子查詢配合完成分頁邏輯。
Select * from table limit 1000000, 10
Select * from table where id in (select pk from table limit 100000, 10)
以上是mysql進(jìn)行sql優(yōu)化的方法的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!