sql 語(yǔ)句優(yōu)化的30種方法
優(yōu)采云 發(fā)布時(shí)間: 2022-09-03 21:08sql 語(yǔ)句優(yōu)化的30種方法
大家好,我是頂級架構師。
1.對查詢(xún)進(jìn)行優(yōu)化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。2.應盡量避免在 where 子句中使用!=或操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描。3.應盡量避免在 where 子句中對字段進(jìn)行 null 值判斷,否則將導致引擎放棄使用索引而進(jìn)行全表掃描,如:
select?id?from?t?where?num?is?null?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;visibility: visible;font-size: 15px;line-height: 18px;" />
可以在num上設置默認值0,確保表中num列沒(méi)有null值,然后這樣查詢(xún):
select?id?from?t?where?num=0?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;visibility: visible;font-size: 15px;line-height: 18px;" />
4.應盡量避免在 where 子句中使用 or 來(lái)連接條件,否則將導致引擎放棄使用索引而進(jìn)行全表掃描,如:
select?id?from?t?where?num=10?or?num=20?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;visibility: visible;font-size: 15px;line-height: 18px;" />
可以這樣查詢(xún):
select?id?from?t?where?num=10?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />union?all?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />select?id?from?t?where?num=20?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
5.下面的查詢(xún)也將導致全表掃描:
select?id?from?t?where?name?like?'%abc%'?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
若要提高效率,可以考慮全文檢索。
6.in 和 not in 也要慎用,否則會(huì )導致全表掃描,如:
select?id?from?t?where?num?in(1,2,3)?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
對于連續的數值,能用 between 就不要用 in 了:
select?id?from?t?where?num?between?1?and?3?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
7.如果在 where 子句中使用參數,也會(huì )導致全表掃描。因為SQL只有在運行時(shí)才會(huì )解析局部變量,但優(yōu)化程序不能將訪(fǎng)問(wèn)計劃的選擇推遲到運行時(shí);它必須在編譯時(shí)進(jìn)行選擇。然而,如果在編譯時(shí)建立訪(fǎng)問(wèn)計劃,變量的值還是未知的,因而無(wú)法作為索引選擇的輸入項。如下面語(yǔ)句將進(jìn)行全表掃描:
select?id?from?t?where?num=@num?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
可以改為強制查詢(xún)使用索引:
select?id?from?t?with(index(索引名))?where?num=@num?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
8.應盡量避免在 where 子句中對字段進(jìn)行表達式操作,這將導致引擎放棄使用索引而進(jìn)行全表掃描。如:
select?id?from?t?where?num/2=100?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
應改為:
select?id?from?t?where?num=100*2?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
9.應盡量避免在where子句中對字段進(jìn)行函數操作,這將導致引擎放棄使用索引而進(jìn)行全表掃描。如:
select?id?from?t?where?substring(name,1,3)='abc'--name以abc開(kāi)頭的id?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />select?id?from?t?where?datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />
應改為:
<p>select?id?from?t?where?name?like?'abc%'?<br mp-original-font-size="15" mp-original-line-height="18" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 15px;line-height: 18px;" />select?id?from?t?where?createdate>='2005-11-30'?and?createdate