第一篇:select語句性能優(yōu)化小結
對查詢進行優(yōu)化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
3.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
4.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
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 也要慎用,否則會導致全表掃描,如: select id from t where num in(1,2,3)
對于連續(xù)的數(shù)值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.下面的查詢也將導致全表掃描:
select id from t where name like '%abc%' 若要提高效率,可以考慮全文檢索。
7.如果在 where 子句中使用參數(shù),也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
select id from t where num=@num 可以改為強制查詢使用索引:
select id from t with(index(索引名))where num=@num
8.應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100 應改為:
select id from t where num=100*2
9.應盡量避免在where子句中對字段進行函數(shù)操作,這將導致引擎放棄使用索引而進行全表掃描。如:
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 應改為:
select id from t where name like 'abc%' select id from
t
where
createdate>='2005-11-30'
and createdate<'2005-12-1'
10.不要在 where 子句中的“=”左邊進行函數(shù)、算術運算或其他表達式運算,否則系統(tǒng)將可能無法正確使用索引。
11.在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。
12.不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統(tǒng)資源的,應改成這樣: create table #t(...)
13.很多時候用 exists 代替 in 是一個好的選擇:
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)
14.并不是所有索引對查詢都有效,SQL是根據(jù)表中數(shù)據(jù)來進行查詢優(yōu)化的,當索引列有大量數(shù)據(jù)重復時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。詳細講解提高數(shù)據(jù)庫查詢效率的實用方法
16.應盡可能的避免更新 clustered 索引數(shù)據(jù)列,因為 clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調(diào)整,會耗費相當大的資源。若應用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應將該索引建為 clustered 索引。
17.盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。
18.盡可能的使用 varchar/nvarchar 代替 char/nchar,因為首先變長字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。
19.任何地方都不要使用 select * from t,用具體的字段列表代替“*”,不要返回用不到的任何字段。
20.盡量使用表變量來代替臨時表。如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。
21.避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。
22.臨時表并不是不可使用,適當?shù)厥褂盟鼈兛梢允鼓承├谈行В纾斝枰貜鸵么笮捅砘虺S帽碇械哪硞€數(shù)據(jù)集時。但是,對于一次性事件,最好使用導出表。
23.在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應先create table,然后insert。
24.如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table,然后 drop table,這樣可以避免系統(tǒng)表的較長時間鎖定。
25.盡量避免使用游標,因為游標的效率較差,如果游標操作的數(shù)據(jù)超過1萬行,那么就應該考慮改寫。
26.使用基于游標的方法或臨時表方法之前,應先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。
27.與臨時表一樣,游標并不是不可使用。對小型數(shù)據(jù)集使用 FAST_FORWARD 游標通常要優(yōu)于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數(shù)據(jù)時。在結果集中包括“合計”的例程通常要比使用游標執(zhí)行的速度快。如果開發(fā)時間允許,基于游標的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。
28.在所有的存儲過程和觸發(fā)器的開始處設置 SET NOCOUNT ON,在結束時設置 SET NOCOUNT OFF。無需在執(zhí)行存儲過程和觸發(fā)器的每個語句后向客戶端發(fā)送 DONE_IN_PROC 消息。
29.盡量避免大事務操作,提高系統(tǒng)并發(fā)能力。
30.盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應該考慮相應需求是否合理。
1.對查詢進行優(yōu)化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
2.應盡量避免使用 left join 和 null 值判斷。left join 比 inner join 消耗更多的資源,因為它們包含與 null(不存在)數(shù)據(jù)匹配的數(shù)據(jù),所以如果可以重新編寫查詢以使得該查詢不使用任何 inner join,則會得到相應的回報。
例如有兩表: product(product_id int not null,product_type_id int null,...),產(chǎn)品表,product_id 為大于0的整數(shù),product_type_id 與表 product_type 關聯(lián),但可為空,因為有的產(chǎn)品沒有類別
product_type(product_type_id not null,product_type_name null,...),產(chǎn)品類別表
此時要關聯(lián)兩表后查詢 product 的內(nèi)容,馬上會想到使用 inner join,但下面有一種方法可避免使用 inner join :
在 product_type 中增加一條記錄:0,'',...,并將 product 的 product_type_id 設置為 not null,當產(chǎn)品沒有類別時將其 product_type_id 設為0,這樣查詢就可以使用 inner join 了。
3.應盡量避免在 where 子句中使用!=或<>操作符,否則引擎可能放棄使用索引而進行全表掃描。
4.應盡量避免在 where 子句中使用 or 來連接條件,否則將可能導致引擎放棄使用索引而進行全表掃描,如有表 t,key1、key2 上建有索引,需要下面的存儲過程:
create procedure select_proc1 @key1 int=0,@key2 int=0 as begin
select key3 from t
where(@key1=0 or key1=@key1)and(@key2=0 or key2=@key2)end go
這個存儲過程會導致全表掃描,可作如下修改:
create procedure select_proc2 @key1 int=0,@key2 int=0 as begin
if @key1 <>0 and @key2<>0 select key3 from t
where key1=@key1 and key2=@key2 else
if @key1<>0
select key3 from t where key1=@key1 else
select key3 from t where key2=@key2 end go
更改后雖然代碼增加了,但效率提高了。
5.in 和 not in 也要慎用,如:
select id from t where num in(1,2,3)
對于連續(xù)的數(shù)值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
6.下面的查詢也將導致全表掃描:
select id from t where name like '%abc%' 若要提高效率,可以考慮全文檢索。
7.如果在 where 子句中使用參數(shù),也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
select id from t where num=@num 可以改為強制查詢使用索引:
select id from t with(index(索引名))where num=@num
8.應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100 應改為:
select id from t where num=100*2
9.應盡量避免在where子句中對字段進行函數(shù)操作,這將導致引擎放棄使用索引而進行全表掃描。如:
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 應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要在 where 子句中的“=”左邊進行函數(shù)、算術運算或其他表達式運算,否則系統(tǒng)將可能無法正確使用索引。
11.在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。
12.不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統(tǒng)資源的,應改成這樣:
create table #t(...)13.很多時候用 exists 代替 in 是一個好的選擇:
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)
14.并不是所有索引對查詢都有效,SQL 是根據(jù)表中數(shù)據(jù)來進行查詢優(yōu)化的,當索引列有大量數(shù)據(jù)重復時,SQL查詢可能不會去利用索引,如一表中有字段 sex,male、female 幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert、update 及 delete 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
16.應盡可能的避免更新 clustered 索引數(shù)據(jù)列,因為 clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調(diào)整,會耗費相當大的資源。若應用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應將該索引建為 clustered 索引。
17.盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。
18.盡可能的使用 varchar/nvarchar 代替 char/nchar,因為首先變長字段存儲空間小,可以節(jié)省存儲空間(定長字段即使在數(shù)據(jù)為null時也需要定長的存儲空間(7.0及更高版本)),其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些,而且每頁(8KB)可能存儲更多的記錄數(shù),這樣也可以減少I/O的消耗而提高性能。
19.任何地方都不要使用 select * from t,用具體的字段列表代替“*”,不要返回用不到的任何字段。
20.盡量使用表變量來代替臨時表。如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。
21.避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。
22.臨時表并不是不可使用,適當?shù)厥褂盟鼈兛梢允鼓承├谈行В纾斝枰貜鸵么笮捅砘虺S帽碇械哪硞€數(shù)據(jù)集時。但是,對于一次性事件,最好使用導出表。
23.在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應先 create table,然后 insert。
24.如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table,然后 drop table,這樣可以避免系統(tǒng)表的較長時間鎖定。
25.盡量避免使用游標,因為游標的效率較差,如果游標操作的數(shù)據(jù)超過1萬行,那么就應該考慮改寫。
1.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如: select id from t where num is null 可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0 2.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。優(yōu)化器將無法通過索引來確定將要命中的行數(shù),因此需要搜索該表的所有行。
3.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
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 4.in 和 not in 也要慎用,因為IN會使系統(tǒng)無法使用索引,而只能直接搜索表中的數(shù)據(jù)。如:
select id from t where num in(1,2,3)對于連續(xù)的數(shù)值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 5.盡量避免在索引過的字符數(shù)據(jù)中,使用非打頭字母搜索。這也使得引擎無法利用索引。見如下例子:
SELECT * FROM T1 WHERE NAME LIKE ?%L%‘ SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=‘L‘ SELECT * FROM T1 WHERE NAME LIKE ?L%‘
即使NAME字段建有索引,前兩個查詢依然無法利用索引完成加快操作,引擎不得不對全表所有數(shù)據(jù)逐條操作來完成任務。而第三個查詢能夠使用索引來加快操作。
6.必要時強制查詢優(yōu)化器使用某個索引,如在 where 子句中使用參數(shù),也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描: select id from t where num=@num 可以改為強制查詢使用索引:
select id from t with(index(索引名))where num=@num 7.應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如: SELECT * FROM T1 WHERE F1/2=100 應改為: SELECT * FROM T1 WHERE F1=100*2 SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=‘5378‘ 應改為: SELECT * FROM RECORD WHERE CARD_NO LIKE ?5378%‘ SELECT member_number, first_name, last_name FROM members WHERE DATEDIFF(yy,datofbirth,GETDATE())> 21 應改為: SELECT member_number, first_name, last_name FROM members WHERE dateofbirth < DATEADD(yy,-21,GETDATE())即:任何對列的操作都將導致表掃描,它包括數(shù)據(jù)庫函數(shù)、計算表達式等等,查詢時要盡可能將操作移至等號右邊。
8.應盡量避免在where子句中對字段進行函數(shù)操作,這將導致引擎放棄使用索引而進行全表掃描。如: select id from t where substring(name,1,3)=‘a(chǎn)bc‘–name以abc開頭的id select id from t where datediff(day,createdate,‘2005-11-30′)=0–?2005-11-30‘生成的id 應改為: select id from t where name like ?abc%‘ select id from t where createdate>=‘2005-11-30′ and createdate<‘2005-12-1′
9.不要在 where 子句中的―=‖左邊進行函數(shù)、算術運算或其他表達式運算,否則系統(tǒng)將可能無法正確使用索引。
10.在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。
11.很多時候用 exists是一個好的選擇: 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)SELECT SUM(T1.C1)FROM T1 WHERE((SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)SELECT SUM(T1.C1)FROM T1WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)兩者產(chǎn)生相同的結果,但是后者的效率顯然要高于前者。因為后者不會產(chǎn)生大量鎖定的表掃描或是索引掃描。
如果你想校驗表里是否存在某條紀錄,不要用count(*)那樣效率很低,而且浪費服務器資源。可以用EXISTS代替。如: IF(SELECT COUNT(*)FROM table_name WHERE column_name = ?xxx‘)可以寫成:
IF EXISTS(SELECT * FROM table_name WHERE column_name = ?xxx‘)
經(jīng)常需要寫一個T_SQL語句比較一個父結果集和子結果集,從而找到是否存在在父結果集中有而在子結果集中沒有的記錄,如: SELECT a.hdr_key FROM hdr_tbl a—-tbl a 表示tbl用別名a代替
WHERE NOT EXISTS(SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key)SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN(SELECT hdr_key FROM dtl_tbl)三種寫法都可以得到同樣正確的結果,但是效率依次降低。12.盡量使用表變量來代替臨時表。如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。
13.避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。14.臨時表并不是不可使用,適當?shù)厥褂盟鼈兛梢允鼓承├谈行В纾斝枰貜鸵么笮捅砘虺S帽碇械哪硞€數(shù)據(jù)集時。但是,對于一次性事件,最好使用導出表。
15.在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應先create table,然后insert。
16.如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table,然后 drop table,這樣可以避免系統(tǒng)表的較長時間鎖定。
17.在所有的存儲過程和觸發(fā)器的開始處設置 SET NOCOUNT ON,在結束時設置 SET NOCOUNT OFF。無需在執(zhí)行存儲過程和觸發(fā)器的每個語句后向客戶端發(fā)送 DONE_IN_PROC 消息。18.盡量避免大事務操作,提高系統(tǒng)并發(fā)能力。19.盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應該考慮相應需求是否合理。
20.避免使用不兼容的數(shù)據(jù)類型。例如float和int、char和varchar、binary和varbinary是不兼容的。數(shù)據(jù)類型的不兼容可能使優(yōu)化器無法執(zhí)行一些本來可以進行的優(yōu)化操作。例如: SELECT name FROM employee WHERE salary > 60000 在這條語句中,如salary字段是money型的,則優(yōu)化器很難對其進行優(yōu)化,因為60000是個整型數(shù)。我們應當在編程時將整型轉化成為錢幣型,而不要等到運行時轉化。
21.充分利用連接條件,在某種情況下,兩個表之間可能不只一個的連接條件,這時在 WHERE 子句中將連接條件完整的寫上,有可能大大提高查詢速度。例:
SELECT SUM(A.AMOUNT)FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO SELECT SUM(A.AMOUNT)FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO=B.ACCOUNT_NO 第二句將比第一句執(zhí)行快得多。
22、使用視圖加速查詢
把表的一個子集進行排序并創(chuàng)建視圖,有時能加速查詢。它有助于避免多重排序 操作,而且在其他方面還能簡化優(yōu)化器的工作。例如: SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 AND cust.postcode>―98000‖ ORDER BY cust.name 如果這個查詢要被執(zhí)行多次而不止一次,可以把所有未付款的客戶找出來放在一個視圖中,并按客戶的名字進行排序: CREATE VIEW DBO.V_CUST_RCVLBES AS SELECT cust.name,rcvbles.balance,……other columns FROM cust,rcvbles WHERE cust.customer_id = rcvlbes.customer_id AND rcvblls.balance>0 ORDER BY cust.name 然后以下面的方式在視圖中查詢: SELECT * FROM V_CUST_RCVLBES WHERE postcode>―98000‖
視圖中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁盤I/O,所以查詢工作量可以得到大幅減少。
23、能用DISTINCT的就不用GROUP BY SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID 可改為:
SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10 24.能用UNION ALL就不要用UNION UNION ALL不執(zhí)行SELECT DISTINCT函數(shù),這樣就會減少很多不必要的資源
35.盡量不要用SELECT INTO語句。
SELECT INOT 語句會導致表鎖定,阻止其他用戶訪問該表。上面我們提到的是一些基本的提高查詢速度的注意事項,但是在更多的情況下,往往需要反復試驗比較不同的語句以得到最佳方案。最好的方法當然是測試,看實現(xiàn)相同功能的SQL語句哪個執(zhí)行時間最少,但是數(shù)據(jù)庫中如果數(shù)據(jù)量很少,是比較不出來的,這時可以用查看執(zhí)行計劃,即:把實現(xiàn)相同功能的多條SQL語句考到查詢分析器,按CTRL+L看查所利用的索引,表掃描次數(shù)(這兩個對性能影響最大),總體上看詢成本百分比即可。
第二篇:SQL語句性能優(yōu)化
我也做了很長時間醫(yī)療軟件,也寫過不少sql優(yōu)化,沒有詳細記錄下來,個人感覺下面轉載的更符合醫(yī)院醫(yī)療軟件實際業(yè)務,很認可大部分所寫的原則,固轉載過來,以作借鑒。軟件的根本還是在于更細更精,在于從客戶的實際使用考慮問題。
性能優(yōu)化原則1:永遠避免困境
利用緩存把字典數(shù)據(jù)取到中間服務器或是客戶端替代直接sql查詢,如,門診醫(yī)生站把字典下載到客戶端,減少執(zhí)行次數(shù)。
一次性取數(shù)據(jù)到客戶端,然后再逐條處理,而不是分次取數(shù)據(jù),處理好一條數(shù)據(jù)再取下一條再處理。例:門診收費取hjcfmxk例子,原來是一張?zhí)幏綏l明細都查詢一次,查詢后再處理,現(xiàn)改為一次把所有明細都取過來,然后一條條處理
盡量減少光標,看能不能用臨時表
性能優(yōu)化原則2:kiss原則
對于where 條件中的左邊可以利用索引的字段Keep it simple stupid,左邊盡量避免用函數(shù)(substring,isnull,upper,lower),參加計算+,-*/
例子1:select * from ZY_BRFYMXK where substring(zxrq,1,8)='20081212‘
select * from ZY_BRFYMXK where zxrq between '2008121200' and '2008121224' 例子2:
select * from zy_detail_charge where SUBSTRING(patient_id,1,10)=
substring('000005090600',1,10)這句耗時30秒以上
select * from zy_detail_charge where patient_id like substring('000005090600',1,10)+'%' 這句耗時2秒以內(nèi)
性能優(yōu)化原則3:盡可能利用到索引
例:select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0
select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0 and b.syxh=3
性能優(yōu)化原則4:or,避而遠之
對于索引字段盡力避免用or,普通字段可以用or,解決要么分解成多個sql,要么用業(yè)務規(guī)則避免,例:declare @rq1 ut_rq16,@syxh ut_syxh
select @rq1='20081201'
select @syxh=157
性能優(yōu)化原則5:避免大批量數(shù)據(jù)取到前臺
例: select * from ZY_BRSYK cyrq between ‘20080901’ and ‘20081201‘,對于大醫(yī)院每天100多人,90天是9000條數(shù)據(jù)
性能優(yōu)化原則6:事務,盡可能的短吧
所有計算、對臨時表的更新都應但放在事務外,事務中最好只有更新和插入正式表操作.因為事務中產(chǎn)生的鎖只有在commit tran是才會釋放。
性能優(yōu)化原則7:熱表,留在最后吧
熱表是頻繁調(diào)用的表。如:sf_mzcfk,zy_brfymxk,bq_fyqqk.對于熱表盡量放在事務最后:這樣鎖的時間短。大家都堅持這樣,死鎖的可能性就小。如果都是熱表各個存儲過程更新表的順序應當一樣這樣可以避免死鎖
性能優(yōu)化原則8:創(chuàng)建臨時表一定要避免在事務中作
如create #tempXX(…)
Select * into #tempXX from …
因為創(chuàng)建臨時表會鎖tempdb的系統(tǒng)表
例:生成#temp1放在事務內(nèi)外,用sp_lock2 ‘’觀察結果
if object_id('tempdb..#temp1','U')is not null
drop table #temp1
begin tran
select * into #temp1 from ZY_BRSYK where ryrq>'20080901‘
select * from #temp1
waitfor delay '00:00:10'
commit
性能優(yōu)化原則9:大的報表查詢避免與正常業(yè)務碰撞
如果沒有查詢服務器,那要在存儲過程中限制不能操作加上如:
declare @rq1 ut_rq16,@rq2 ut_rq16,@now ut_rq16
select @rq1=convert(varchar(8),getdate(),112)+'08:00:00'
select @rq1=convert(varchar(8),getdate(),112)+'11:30:00'
select @now=convert(char(8),getdate(),112)+convert(char(8),getdate(),8)
if @now>@rq1 and @now<@rq2
begin
select '上午繁忙時間段不能作此查詢'
return
end
性能優(yōu)化原則10:存儲過程避免大的if…else…
這個常出項在業(yè)務相同表不同的存儲過程中,因為這樣常到if …else …原來醫(yī)技接口中很多這種存儲過程,當時把門診住院業(yè)務放在一個存儲過程中。這樣最大的問題是sql server會根據(jù)sql語句來compile存儲,這個過程會生成優(yōu)化計劃,決定用那個索引。如果存儲過程用到門診表compile一下,到用到住院表是發(fā)現(xiàn)不對,又會compile一下,這樣不停compile.compile很號時間要1-2秒,而且一個存儲過成在compile是,所有調(diào)用這個存儲過程的進程都要在排隊等候,因為他會獨占鎖這個存儲過程
例:usp_yjjk_getwzxxm_old.sql,后改為:
usp_yjjk_getwzxxm.sql, usp_yjjk_getwzxxm_mz.sql,usp_yjjk_getwzxxm_zy.sql
性能優(yōu)化原則11:進攻是最好的防守
在普通編程語句對于數(shù)據(jù)校驗總是用防守辦法先判斷,后再作相應處理。而在sql中先處理再判斷性能會好很多。
--更新藥品庫存。
If exists(select 1 from YK_YKZKC WHERE idm=100 and kcsl>50)
begin
update YK_YKZKC set kcsl=kcsl-50 where idm=100
End
Else begin
rollback tran
Select ‘F庫存不夠’
return
end
--改為
update YK_YKZKC set kcsl=kcsl-50 where idm=100 and kcsl>50
If @@rowcount<=0
Begin
Rollbakc tran
Select ‘F庫存不夠’
end
--取未執(zhí)行的醫(yī)技項目,日表沒有數(shù)據(jù)就到年表中查找
if exists(select a.* from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
begin
select a.* into #temp1 from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
end
else begin
select a.* into #temp1 from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)
end
--改為
Insert into #temp1 select a.*
from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
If @@rowcount=0
Begin
Insert into #temp1 select a.*
from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)
end
性能優(yōu)化原則12:trig最后的手段
Trig(觸發(fā)器)的處理的處理機制是滿足條件時就會在源語句后面加上trig中的代碼進行執(zhí)行。
它有兩個致命的弊端:(1)不清楚有trig的人會對于執(zhí)行結果感到迷惑。如常有在插入一張表如果主鍵是indentity的值常取用select @@identity。但如是有trig,tring中有表插入操作,這時的@@identity可能就不是想要的值。(2)trig會束縛選擇。如:有一套單據(jù)主表和明細表,當明細表的金額更新時,要同步主表的金額,當程序是一條條更新明細時用trig的作法是每當更新一條明細記錄時都算一處所有明細表的總金額,再去更新主表的金額。這樣有多少條明細就要算多少次,好的作法是不要trig,直接在sql語句中明細更新完明后,一次性算出總金額每條單據(jù)的總金額,再更新主表的金額。
對于trig如果有其他手段就一定要避免用trig.性能優(yōu)化原則13:用戶說好才是真的好
1)有時sql語句性能難以優(yōu)化,但用戶對于系統(tǒng)響應速度還是不滿意。這時可以從業(yè)務分析處理。
如:我們退費模塊錄入發(fā)票號原來是用fph like ‘XXX%’。用戶報怨慢,后來改為先用fph=‘XXX’來查,如查不到再fph like ‘XXX%’。這樣在絕大部情況下速度都非常快,同時也滿足小部分情況下模糊查詢的需求。
如:我們的程序要查日表和年表。如果通過日表union表視圖去查會非常慢,性能也難以優(yōu)化。程序改為普通情況下不查年表,用戶勾上年表標志時才查年表。
(2)查詢統(tǒng)計很多數(shù)據(jù)時間比較長,就以查詢完一部分數(shù)據(jù)后可以顯示這部分數(shù)據(jù)或是用提示,這樣用戶清楚系統(tǒng)在作事情也知道大概進度。這樣情緒上會好很多。
(3)查詢模塊常有一進入時也默認一個查詢,如果性能好,查詢又合用戶心意,這種設計非常好,如果性能不好,那就不是好的設計。用戶對于進入都困難的模塊是沒有好感的。
(4)有戶的耐心與查詢出的記錄成正比。用戶痛恨等待很久卻沒有查詢出記錄。
對于非常慢的查詢,如果有些子查詢非常快可以先作這樣查詢以避免查詢很久卻沒有數(shù)據(jù)出來的情況。如:按病歷號查在院病人所有費有明細,可以先查一下這個病歷是不是有對應病人。
實戰(zhàn)技巧1:用exists、in代替distinct
Distinct實際上是先收集再刪除這樣兩步都耗資源。
Exists,in會隱式過濾掉重復的記錄
例查自2009年以來有金額大于100的藥品的病人
select distinct a.blh,a.hzxm from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and c.zxrq>'2009' and c.zje>100--改為
select a.blh,a.hzxm from ZY_BRXXK a where exists(select 1 from ZY_BRSYK
b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and
c.zxrq>'2009'and c.zje>100)
實戰(zhàn)技巧2:縮短union
select …from A,B,C,D,E1
where(E1的條件)
and(其他表聯(lián)接條件)
union
select …from A,B,C,D,E2
where(E2的條件)
and(其他表接接條件)
改為
select …from A,B,C,D,(select...from E1where(E1條件)
union
select …from E2where(E2條件))E where(其他條件)
當涉及ABCD表部分耗資源而E1,E2不耗資源時是這樣,如果反過來則改后的性能不一定好。查2009年4月后入院的在院病人在2905病區(qū)發(fā)生的所有費用明細
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YK_YPCDMLK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm
union all
select a.hzxm,b.cyrq,d.name,d.xmgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YY_SFXXMK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.ypdm=d.id and c.idm=0
--改為
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),(select ypmc,ypgg,ypdm,idm idm from YK_YPCDMLK union select name,xmgg,id,0 from YY_SFXXMK)d
where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm and c.ypdm=d.ypdm
實戰(zhàn)技巧3:合并sql
把表和where條件類似的兩個或是多個sql合并為一個sql.--查2009年以后的普通、急診、專家掛號人數(shù)
declare @ptghs int,@jzghs int,@zjghs int
select @ptghs=0,@jzghs=0,@zjghs=0
select @ptghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=0
select @jzghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=1
select @zjghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=2
select @ptghs,@jzghs,@zjghs
--改為
select @ptghs=0,@jzghs=0,@zjghs=0
select @ptghs=sum(case when ghlb=0 then 1 else 0 end),@jzghs=sum(case when ghlb=1 then 1 else 0 end), @zjghs=sum(case when ghlb=2 then 1 else 0 end)
from GH_GHZDK where ghrq>'2009'
select @ptghs,@jzghs,@zjghs
實戰(zhàn)技巧4:去掉游標
把游標當作編程語言的for,do---while的方式,很多情況下都可以去掉,如果光標中間sql語句只有一條一般都是可以去掉光標改為一句sql。
--查當天出院出院日期在2009年4月1到9日間病人的zfdj,zfje置為0
declare @syxh ut_syxh
declare cur1 cursor for select syxh from ZY_BRSYK where cyrq>='20090401' and cyrq<'20090410'
open cur1
fetch cur1 into @syxh
while @@fetch_status=0
begin
fetch cur1 into @syxh
end
close cur1
deallocate cur1
--改為
update ZY_BRFYMXK set zfdj=0,zfje=0
from ZY_BRFYMXK a,ZY_BRSYK b
where a.syxh=b.syxh and b.cyrq>='20090401' and b.cyrq<'20090410'
實戰(zhàn)技巧5:取代count
利用內(nèi)部函數(shù)代替
declare @count int
select * into #tmep1 from ZY_BRFYMXK WHERE zxrq>'200901'
select @count=@@rowcount—可以得到count值
select @count
select @count=count(*)from #tmep1—可以被取代
select @count
利用exists而不count判斷有沒有記錄
declare @count int
Select @count=count(1)from ZY_BRFYMXK WHERE zxrq>'2009‘
If @count>0 … else ….--改為
If exists(Select 1 from ZY_BRFYMXK WHERE zxrq>'2009’)… else ….
第三篇:Web前端頁面性能優(yōu)化小結
Web前端頁面性能優(yōu)化小結
Web前端頁面性能優(yōu)化小結
影響用戶訪問的最大部分是前端的頁面。網(wǎng)站的劃分一般為二:前端和后臺。我們可以理解成后臺是用來實現(xiàn)網(wǎng)站的功能的,比如:實現(xiàn)用戶注冊,用戶能夠為文章發(fā)表評論等等。而前端呢?其實應該是屬于功能的表現(xiàn)。
而我們建設網(wǎng)站的目的是什么呢?不就是為了讓目標人群來訪問嗎?所以我們可以理解成前端才是真正和用戶接觸的。
除了后臺需要在性能上做優(yōu)化外,其實前端的頁面更需要在性能優(yōu)化上下功夫,只有這樣才能給我們的用戶帶來更好的用戶體驗。不僅僅如此,如果前端優(yōu)化得好,他不僅可以為企業(yè)節(jié)約成本,他還能給用戶帶來更多的用戶,因為增強的用戶體驗。說了這么多,那么我們應該如何對我們前端的頁面進行性能優(yōu)化呢?
前端的頁面主要包括xhtml,css,js。其實xhtml就是現(xiàn)實中所談到的內(nèi)容,頁面的內(nèi)容:文字,圖片,flash,視頻等。
而前端開發(fā)工作者可以控制的是什么呢?那就是xhtml,css,js的代碼及相應的修飾(背景)圖片。下面我就根據(jù)我自己的經(jīng)驗來說說:
一、提倡前端開發(fā)工程師在書寫xhtml的時候做到結構語義化。結構中主要包括了head和body兩個部分,但是我們經(jīng)常說的是結構語義化主要是body中的標簽,但是我在這里還是簡單的說一下 head,head中其實包括了一些對于我們seo很有用的一些東西,比如
title,description,keywords,這些東西在蜘蛛抓取的時候都是有幫助的,當然,還有其他的一些,我在此就不一一說明了,比如設置緩存等一些其他的信息。那么body中的話,包括的標簽就很多了,我覺得作為一個合格的前端開發(fā)人員你應該去熟悉他們,比如div,span,h,ul,ol,dl,p等等這類的標簽的使用。應該非常合理,還有就是注意h標簽的斷層,及h1標簽的使用,這些都是非常重要的。同時在我們的結構中不要出現(xiàn)style和onclick這樣的內(nèi)聯(lián)的樣式和事件.。希望大家能夠注意結構與表現(xiàn)、行為的分離。(ps:標簽語義化的好處:1.有利于搜索引擎;2.結構清晰的html在團隊合作中的作用,就不必說了吧;3.有利于盲人屏幕閱讀器。至于如何做到標簽語義化,就看個人的理解了,這方面我也覺得模糊,跟個人的習慣估計也有一定的關系,總之鄒惠斌老師是認為我的標簽不語義的。)
二、css(http://zhi.ujiuye.com/web/css/),js文件數(shù)量及大小的優(yōu)化 那么關于css、js的優(yōu)化的話,一般情況下建議css和js采用外聯(lián)式。但是如果你的頁面內(nèi)容比較多,設計師把整個效果做得比較花的話,恐怕 css就非常多了,那么這種情況下,你一定要把你的css規(guī)劃好,盡量的采用縮寫,這樣可以減少css文件的大小,那么對css做相應的規(guī)劃也可以減少 css的個數(shù),減少http請求數(shù),js同理。(ps:減少重復性代碼,代碼重復利用,在這里顯得特別重要)
三、背景圖片數(shù)量及大小的優(yōu)化
當我們將設計師的設計稿還原成靜態(tài)頁面后,除非頁面所有的修飾全是色塊,內(nèi)容全是文字,沒有圖片,如果不是這樣的話,那么我們需要對圖片做優(yōu)化處理。當然內(nèi)容圖片我們是沒有辦法了,因為他是屬于內(nèi)容部分的,一般情況是由于編輯處理,當然,我在還是有一個小小的建議,如果我們的網(wǎng)站中需要有內(nèi)容圖片,希望編輯能夠將他們最優(yōu)化以后,在進行上傳,一會兒告訴我的方法,下面我在說說,作為前端開發(fā)應該如何處理我們的修飾(背景)圖片。由于我們的背景圖片數(shù)量比較多,這樣的話,會給服務器帶來影響,增加了http請求數(shù),我們是否有一種好的解決辦法呢?這個答案是肯定的,如果你是一個合格的前端開發(fā),你應該清楚,在我們的css定義背景的時候,可以通過坐標來實現(xiàn)對背景進行定位的,既然如此,那么我們可以將這些背景合并起來,這樣即可減少http請求數(shù),同時,我們在背景整合的時候,也需要考慮圖片質(zhì)量,同時也需要考慮圖片的大小(ps:這里建議使用png8格式的圖片結合css sprite,同樣的圖片,png8格式會相對來比gif小)
四、內(nèi)容圖片的大小的優(yōu)化
其實剛才已經(jīng)說了內(nèi)容圖片的問題,那么我在這里呢,告訴大家一個比較簡單的方法,就是使用雅虎提供的一個工具。他就是smushit:http:// 規(guī)范在文檔 內(nèi)加載你的樣式表。
對于擁有較大瀏覽量的首頁來說,有一種技術可以平衡內(nèi)置代碼帶來的 http 請求減少與通過使用外部文件進行緩存帶來的好處。其中一個就是在首頁中內(nèi)置 javascript 和 css,但是在頁面下載完成后動態(tài)下載外部文件,在子頁面中使用到這些文件時,它們已經(jīng)緩存到瀏覽器了。
更多知識干貨分享,盡在中公優(yōu)就業(yè),>>>點擊進入。
點擊查看>>>中公IT優(yōu)就業(yè)封閉式培訓,包食宿,學費貸款,交通補貼,推薦就業(yè)
第四篇:6多分支結構——select語句
第三節(jié)多分支結構——select語句教學設計
一、教學目標
1、知識與技能:
(1)充分理解多分支結構的流程。
(2)能夠利用多分支結構的思想解決實際問題。
2、過程與方法: 培養(yǎng)學生獨立思考的能力、靈活運用所學知識解決問題的能力。
3、情感態(tài)度與價值觀:(1)增強學生思維的嚴密性。
(2)善于發(fā)現(xiàn)問題,敢于提出疑問并能夠針對疑問積極主動的思考解決。
二、教學重難點
1、重點:理解多分支結構的流程。
2、難點:理解程序中流程的代碼描述。
三、教學過程
1、游戲引入
通過學生喜歡的心理測試的小游戲再將學生的注意力吸引到本課中來的同時,讓學生初步體會,選擇不同的面包能夠得到不同的測試結果。
(設計意圖:從游戲入手,滿足了學生愛玩的童心的同時,集中了學生的注意了,拉近了師生之間的距離,也為后面的問題做好鋪墊。)
2、初步理解
教師通過解密心理測試的秘密引出游戲的背后的支持者:程序代碼,帶領學生邊玩游戲邊看代碼,從中發(fā)現(xiàn)規(guī)律。同時提出問題:玩游戲的過程當中如果在文本框中輸入3,測試結果變成“你是灰太狼”,要達到這個要求需要對游戲代碼做怎樣的修改?并說明原因
(代碼是比較抽象的概念,很難通過定義理解它,通過修改代碼從形式上讓代碼成為學生自己的東西,接觸學生看到代碼的陌生心理,同時讓學生初步體會不同的選擇對應不同的結果。)
3、深入剖析
通過理解星貓心理測試的過程,將不同的面包對應不同的測試結果轉化為流程圖中不同的條件對應不同的語句組,通過心理測試的代碼導出程序基本格式。
(設計意圖:圖形是比較直觀好理解的表現(xiàn)形式,通過圖形引出結構的流程圖,結合流程圖分析該圖是如何應用程序語句描述的,以具體的程序語句對照理解語句格式的基本結構也就不難了。)
4、模擬練習
以程序填空的形式完成分蛋游戲,進一步體會不同的年齡段對應不同的禮物,體驗調(diào)試程序帶來的快樂和成就感,在這一過程中要演示學生的成果,適時給出表揚。
(設計意圖:對于初中學生來說,本節(jié)課只需要理解多分支結構的執(zhí)行過程,理解不同的條件對應執(zhí)行不同的語句組,代碼只需要簡單了解。通過流程圖理解游戲在程序中的執(zhí)行過程,在通過代碼填空,加強對結構的理解。)
5、深入提高
通過思考心理測試當中沒有想選擇的面包的特殊情況的處理方法,引出當表達式對于條件1到條件N都不符合時的處理辦法case else 語句組N+1.培養(yǎng)學生思考問題的嚴密性。
(設計意圖:程序設計要求思維嚴密,考慮到所有可能出現(xiàn)的情況,通過具體的實例引領學生思考特殊情況并思考特殊情況的處理辦法,這樣就把抽象的問題具體化,能夠幫助學生理解,并應用到解決問題的過程當中去。)
6、小結
通過兩個游戲的流程圖以及統(tǒng)一的流程圖,進而引出專業(yè)術語多分支結構——select語句。
通過小結,把課堂教學傳授的知識盡快化為學生的素質(zhì);使學生更深刻地理解兩個游戲的執(zhí)行流程的同時引出本課的課題,這種結構就是VB中的多分支結構,起到畫龍點睛的作用。
7、知識深化
課后思考題:完成成績評價系統(tǒng),思考兩種流程圖的區(qū)別。(設計意圖:應用所學知識解決問題是最終目的,通過完成成績評價系統(tǒng)可以將所學知識應用到實際問題中去,通過思考兩種流程圖的區(qū)別能夠提高思維的嚴密性。)
四、教學反思
本節(jié)以設計四則運算器為重點講了Select語句的基本格式。通 過上節(jié)課IF語句的學習,學生對編程思想基本有了一定的了解,因此根據(jù)本節(jié)內(nèi)容較多的特點,在授課時除重點對Select語句格式及執(zhí)行過程詳解外,其他內(nèi)容讓學生參照教科書自己完成。并將一些課后內(nèi)容拿到課堂上來,使一些接受能力強,完成速度快的學生可以“吃得飽”。用任務驅動和小組合作的形式,對能力稍差的同學也可以有所帶動。通過課后幫助家長設計薪金所得稅程序,使學生對納稅意識有初步了解,增強學生依法納稅道德意識。
第五篇:SQL語句 SELECT LIKE like用法詳解
SQL語句 SELECT LIKE like用法詳解 在SQL結構化查詢語言中,LIKE語句有著至關重
要的作用。LIKE語句的語法格式是:select * from 表名 where 字段名 like 對
應值(子串),它主要是針對字符型字段的,它的作用是在一個字符型字段列中檢索包含對
應子串的。A:% 包含零個或多個字符的任意字符串:
1、LIKE'Mc%' 將搜索以字母 Mc 開
頭的所有字符串(如 McBadden)。
2、LIKE'%inger' 將搜索以字母 inger 結尾的所有字符
串(如 Ringer、Stringer)。
3、LIKE'%en%' 將搜索在任何位置包含字母 en 的所有字符串
(如 Bennet、Green、McBadden)。B:_(下劃線)任何單個字符:LIKE'_heryl' 將搜索以
字母 heryl 結尾的所有六個字母的名稱(如 Cheryl、Sheryl)。C:[ ] 指定范圍([a-f])或
集合([abcdef])中的任何單個字符: 1,LIKE'[CK]ars[eo]n' 將搜索下列字符串:Carsen、Karsen、Carson 和 Karson(如 Carson)。
2、LIKE'[M-Z]inger' 將搜索以字符串 inger 結
尾、以從 M 到 Z 的任何單個字母開頭的所有名稱(如 Ringer)。D:[^] 不屬于指定范
圍([a-f])或集合([abcdef])的任何單個字符:LIKE'M[^c]%' 將搜索以字母 M 開頭,并且
第二個字母不是 c 的所有名稱(如MacFeather)。E:* 它同于DOS命令中的通配符,代
表多個字符:c*c代表cc,cBc,cbc,cabdfec等多個字符。F:?同于DOS命令中的?通配符,代表單個字符 :b?b代表brb,bFb等 G:# 大致同上,不同的是代只能代表單個數(shù)字。k#k
代表k1k,k8k,k0k。F:[!] 排除 它只代表單個字符下面我們來舉例說明一下:例
1,查詢name字段中包含有“明”字的。select * from table1 where name like '%明%'例2,查詢name字段中以“李”字開頭。select * from table1 where name like '李*'例3,查詢name字段中含有數(shù)字的。select * from table1 where name like '%[0-9]%'例4,查詢name字段中含有小寫字母的。select * from table1 where name like '%[a-z]%'例5,查詢name字段中不含有數(shù)字的。select * from table1 where name like '%[!0-9]%'以上例子能列出什么值來顯而易見。但在這里,我們著重要說明的是通配符“*”與“%”的區(qū)別。很多朋友會問,為什么我在以上查詢時有個別的表示所有字符的時候用
“%”而不用“*”?先看看下面的例子能分別出現(xiàn)什么結果:select * from table1 where
name like '*明*'select * from table1 where name like '%明%'大家會看到,前
一條語句列出來的是所有的記錄,而后一條記錄列出來的是name字段中含有“明”的記錄,所以說,當我們作字符型字段包含一個子串的查詢時最好采用“%”而不用“*”,用“*”的時候只在開頭或者只在結尾時,而不能兩端全由“*”代替任意字符的情況下。