❶ 如何提高sql查詢效率
轉帖一下
1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 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)
對於連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.下面的查詢也將導致全表掃描:
select id from t where name like '%abc%'
若要提高效率,可以考慮全文檢索。
7.如果在 where 子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變數,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然 而,如果在編譯時建立訪問計劃,變數的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
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子句中對欄位進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
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 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
11.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。
12.不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣:
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是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有欄位sex,male、female幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。
15.索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。
16.應盡可能的避免更新 clustered 索引數據列,因為 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新 clustered 索引數據列,那麼需要考慮是否應將該索引建為 clustered 索引。
17.盡量使用數字型欄位,若只含數值信息的欄位盡量不要設計為字元型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字元串中每一個字元,而對於數字型而言只需要比較一次就夠了。
18.盡可能的使用 varchar/nvarchar 代替 char/nchar ,因為首先變長欄位存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的欄位內搜索效率顯然要高些。
19.任何地方都不要使用 select * from t ,用具體的欄位列表代替「*」,不要返回用不到的任何欄位。
20.盡量使用表變數來代替臨時表。如果表變數包含大量數據,請注意索引非常有限(只有主鍵索引)。
21.避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
22.臨時表並不是不可使用,適當地使用它們可以使某些常式更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對於一次性事件,最好使用導出表。
23.在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然後insert。
24.如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
25.盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那麼就應該考慮改寫。
26.使用基於游標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。
27.與臨時表一樣,游標並不是不可使用。對小型數據集使用 FAST_FORWARD 游標通常要優於其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括「合計」的常式通常要比使用游標執行的速度快。如果開發時 間允許,基於游標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。
28.在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。
29.盡量避免大事務操作,提高系統並發能力。
30.盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理
❷ 如何提高select between and 的查詢速度
1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 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
❸ sql語句的效率問題
我以前用Sybase的,oracle語法可能和sybase有所出入,就不直接給你修改了,下面我提6點建議:
1、b in ('1','2','3','4','5','6')
如果b的類型是整型,這句話應修改成 b between ('1','6')
2、a > '11111' and a < '99999'
應修改成a between ('11111','99999')
between 這個詞在oracle裡面應該也有對應的語句,請確認。
3、凡是做count(*)運算的,速度都很慢,尤其是有著500萬數據的大表,如果你不是僅僅查詢一次的話,強烈建議根據查詢條件建索引,不一定要唯一性索引。
4、建索引的欄位作為查詢條件時一定要排在where後面的第一位
5、增加行鎖的數量。
6、還有一個辦法就是把b、a從t1表裡抽出來單獨建一個臨時表,(select b,a from t1 into #ttt)然後對ttt表的a欄位建索引,再進行查詢,這個方法最通用,因為你做統計的時候不會引起t1表大面積加鎖從而影響別的用戶的使用。
需要注意的是這個臨時表最好建成動態的,即語句執行完畢後就自行釋放,這樣不會在資料庫中生成垃圾表,影響日後的清理和維護。
❹ between and與in和and與or哪種效率要高
between and效率應該比in高些,建議使用exists
and和or感覺沒有可比性
而且一條sql語句的高低在oracle下還是要看很多方面的
比如:
1.oracle版本
2.optimizer_mode
3.統計信息
4.index
5.數據分布
6.where條件
7.shared pool size
8.database buffer cache
9.table和index的情況.比如table的hwm
等等
最好能有比較具體的SQL拿出來
❺ oracle查詢語句中使用between and 查詢效率高嗎 與to_char相比如何
看你的索引和數據量情況,
如果你的索引是建立在 時間欄位 上的,那麼一般來說,第一個會快
如果你的索引是建立在 to_char('時間欄位','yyyy') 函數上的,那麼一般來說,第二個快
當然還和Oracle資料庫統計的數據量有關。
比如,你表中只有2014年的數據,那麼肯定全部是全表掃描。
❻ SQL語句自帶的分頁,就是最後between 1 and 20這樣的。現在要導出到excel,但因為記錄比較多,百萬級的
select Field1,Field2 from table with(nolock)再加個索引就會快一些,
不想再查詢的話放到內存裡面,第二次再從內存裡面拿數據
❼ PL/SQL中between..and和不等號用哪個好
一般來講,如果不是特殊情況,不建議用不等號,因為不等號會執行全表掃描,
,對於大數據量來講,查詢效率會非常低,而between---and----其實就相當於
范圍查詢> 和 <,如果在這一列是剛好有聚集索引的話,對於大數據集的查詢
來講,效率會明顯提高。
❽ SQL語句中 between and
sql操作符
BETWEEN
...
AND
會選取介於兩個值之間的數據范圍。這些值可以是數值、文本或者日期。
SQL
BETWEEN
語法
SELECT
column_name(s)
FROM
table_name
WHERE
column_name
BETWEEN
value1
AND
value2
Persons
表:
Id
LastName
FirstName
Address
City
1
Adams
John
Oxford
Street
London
2
Bush
George
Fifth
Avenue
New
York
3
Carter
Thomas
Changan
Street
Beijing
4
Gates
Bill
Xuanwumen
10
Beijing
BETWEEN
操作符實例
查詢字母順序顯示介於
"Adams"(包括)和
"Carter"之間的人
sql語句
SELECT
*
FROM
Persons
WHERE
LastName
BETWEEN
'Adams'
AND
'Carter'
結果集:
Id
LastName
FirstName
Address
City
1
Adams
John
Oxford
Street
London
2
Bush
George
Fifth
Avenue
New
York
使用
NOT
BETWEEN
...
AND
就會選擇不再兩個值之間的數據
❾ between 比 in效率高體現在多少數據量上
between and效率應該比in高些,建議使用exists
and和or感覺沒有可比性
而且一條sql語句的高低在oracle下還是要看很多方面的
比如:
1.oracle版本
2.optimizer_mode
3.統計信息
4.index
5.數據分布
6.where條件
7.shared pool size
8.database buffer cache
9.table和index的情況.比如table的hwm
等等
❿ SQL 語句中between and 使用求教
作用:
BETWEEN and操作符在 WHERE 子句中使用,作用是選取介於兩個值之間的數據范圍。
范圍:
操作符 BETWEEN ... AND 會選取介於兩個值之間的數據范圍。這些值可以是數值、文本或者日期。
語法:
SELECT column_name(s)FROM table_name
WHERE column_nameBETWEEN value1 AND value2注意事項:
不同的資料庫對 BETWEEN...AND 操作符的處理方式是有差異的。有些資料庫包含value1 和 value2 有些只包含value1 不包含value2,有些則兩則均不包括。
所以,請檢查你的資料庫是如何處理 BETWEEN....AND 操作符的!
舉例說明(以sql server 2008為列)
(1).建表並且生成數據
create table 銷售清單
(單據編號 varchar(10),
商品 varchar(10),
時間 datetime)
insert into 銷售清單
values ('00001','蘋果','2014-01-01'),
('00002','荔枝','2015-01-01'),
('00003','菊花','2016-01-01'),
('00004','玫瑰','2015-12-01')
-