當前位置:首頁 » 編程語言 » 怎麼讓sql語句更快
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

怎麼讓sql語句更快

發布時間: 2023-05-25 13:01:56

1. 怎麼樣增快sql語句

T-SQL腳本優化技巧:
1)對於SELECT/UPDATE語句必須顯示的定義所有的列,避免使用星號。
2)在執行SELECT/INSERT/UPDATE/DELETE語句時,請考慮執行規劃的重用,盡量考慮用SP-EXECUTESQL存儲過程。
3)優先使用 SELECT...INTO,然後使用 INSERT...SELECT,以避免大量死鎖。
4)如果需要刪除所有的數據,用TRUNCATE TABLE 代替DELETE 。
5)避免使用DISTINCT 語句。
6)如果你需要有限的記錄,通過TOP N代替SET ROWCOUNT來控制排序取值。
7)避免使用SARGABLE的語句在WHERE子句,比如: OR, <>, !=, !<, >!, IS NULL, NOT, NOT IN, NOT LIKE 和LIKE,因為這些操作很難利用已知的索引。
8)避免使用NOT IN,可以採用IN,EXISTS NOT EXISTS和LEFT JOIN 加空值判斷
--NOT EXISTS, 效率最高 SELECT a.hdr_key
FROM hdr_tbl a
WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key) --LEFT JOIN 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 --NOT IN ,效率最低 SELECT hdr_key
FROM hdr_tbl
WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl) 9)使用EXISTS判斷記錄是否存在。
--不好的寫法: IF (SELECT COUNT(*) FROM table_name WHERE column_name = 'xxx') --正確的寫法: IF EXISTS (SELECT * FROM table_name WHERE column_name = 'xxx') 10)避免在GROUP BY中使用HAVING 語句。
11)GROUP BY的語句要盡量簡單,不要進行GROUP BY語句的嵌套,避免在GROUP BY中包含多餘的列
考慮在GROUP BY的列,進行ORDER BY排序,特別在多用戶的環境下。
12)如果需要在一個包含JOIN的SELECT語句進行GROUP BY,請考慮用子查詢代替JOIN. 如果必須使用GROUP BY, GROUP BY 的應該列在同一張表。
13)如果WHERE條件語句有多個AND條件,請確保至少有一個列有索引,如果沒有可以建立多列復合INDEX。
14)對於SQL 無法執行自動優化的WHERE條件語句,可以通過HINTS顯示的制定INDEX來提高查詢的效率。
--可能不好的寫法: SELECT * FROM tblTaskProcessesWHERE nextprocess = 1 AND processid IN (8,32,45) --正確的寫法: SELECT * FROM tblTaskProcesses (INDEX = IX_ProcessID)WHERE nextprocess = 1 AND processid IN (8,32,45) 15)盡可能避免在WHERE條件語句中使用函數計算。
--不好的寫法: WHERE SUBSTRING(firstname,1,1) = 'm' --正確的寫法: WHERE firstname like 'm%' 16)在WHERE條件語句中,避免在函數中包列,如果無法避免,請考慮在該列建立INDEX。
--不好的寫法: 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()) 17)在WHERE條件語句中,避免使用NOT 。
--不好的寫法: WHERE NOT column_name > 5 --正確的寫法: WHERE column_name <= 5 18)在WHERE條件語句中,推薦使用10位的日期函數。
--正確的寫法: SELECT * FROM Northwind.dbo.Orders WHERE OrderDate > '12/31/1997'--不好的寫法: SELECT * FROM Northwind.dbo.Orders WHERE OrderDate > '12/31/97' 19)避免使用UNION,而是用UNION ALL 。
20)使用 SQL-92 標准連接句法,為了提高性能,應優先使用連接,然後使用子查詢或嵌套查詢,表之間的連接使用INNER JOIN,LEFT JOIN 和RIGHT JOIN,不使用CROSS JOIN和多列表方式.。
21)多表關聯避免超過5個,可以通過臨時表(表變數),簡化復雜的關聯。

存儲過程的開發和優化技巧:1)避免使用觸發器TRIGGER,考慮用存儲過程代替觸發器
——與臨時表一樣,游標並不是不可使用。對小型數據集使用FAST_FORWARD 游標通常要優於其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括「合計」的常式通常要比使用游標執行的速度快。如果開發時 間允許,基於游標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。2)考慮用UDF代替存儲過程
——使用表值 UDF 時要小心,因為在變數(而不是常量)中傳遞某個參數時,如果在 WHERE 子句中使用該參數,會導致表掃描。還要避免在一個查詢中多次使用相同的表值 UDF。但是,表值 UDF 確實具有某些非常方便的動態編譯功能。3)對於頻繁調用的存儲過程,考慮用SP_RECOMPILE重新編譯
4)使用輸出語句代替返回整個數據集,輸出語句的執行效率會更加高效
5)在存儲過程的頭部使用SET NOCOUNT ON, 通過@@ROWCOUNT來控制,這樣可以減少網路流量和避免潛在的問題, 而在結束時設置 SET NOCOUNT OFF.
6)不使用SP_作為存儲過程的名稱,建議用USP_,這個會影響資料庫的執行時間.
7)盡可能使用臨時表而使用表變數,表變數可以減少上鎖和重新編譯的次數並且表變數不使用TEMPDB的空間,而是全部使用內存來處理數據.
8)先在常式中創建臨時表,最後再顯式刪除臨時表。將 DDL 與 DML 語句混合使用有助於處理額外的重新編譯活動
9)盡可能不要在流程式控制制語句中使用臨時表,比如:IF .. ELSE, WHILE
10)避免在事務中進行賦值和復雜計算,

--不好的寫法: Create procere proc_1 As Begin Begin transaction -- step 1 verify the data -- step 2 perform calculations -- step 3 get default variable values (date, user info) -- update/insert records commit end --不好的寫法: Create procere proc_1 As Begin -- step 1 verify the data -- step 2 make calculations -- step 3 get default variable values (date, user info) Begin transaction -- update/insert records commit end 上面的一些優化規則只是一般原則,在某些特殊情況下可能會有所差別,如果需要分析T-SQL的性能,可以通過查詢分析器的CTRL+L 顯示執行規劃進行分析,也可以通過 SET STATISTICS PROFILE ON進行分析.

2. 如何修改建表的sql語句使得對某些查詢速度更快

應該是優化查詢吧!
select id,name,age
from aa
如果要限定id號或叢橡者name,age就需哪鄭遲要使用where...and等語句了

select id,name,age
from aa
where id=1
and age=20

如果是要創建索引得話,直接右擊資料庫表,創建聚集索引或者非聚集索引,創建索引的同時還可李李以設置primary key

3. 如何優化SQL語句

一、問題的提出
在應用系統開發初期,由於開發資料庫數據比較少,對於查詢SQL語句,復雜視圖的的編寫等體會不出SQL語句各種寫法的性能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中數據的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的優化。對於海量數據,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的SQL語句,提高系統的可用性。
在多數情況下,Oracle使用索引來更快地遍歷表,優化器主要根據定義的索引來提高性能。但是,如果在SQL語句的where子句中寫的SQL代碼不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種SQL語句就是所謂的劣質SQL語句。在編寫SQL語句時我們應清楚優化器根據何種原則來刪除索引,這有助於寫出高性能的SQL語句。
二、SQL語句編寫注意問題
下面就某些SQL語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的SQL,系統在運行該SQL語句時也不能使用該索引,而同樣使用全表掃描,這就造成了響應速度的極大降低。
1.
IS
NULL

IS
NOT
NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is
null或is
not
null的語句優化器是不允許使用索引的。
2.
聯接列
對於有聯接的列,即使最後的聯接值為一個靜態值,優化器是不會使用索引的。我們一起來看一個例子,假定有一個職工表(employee),對於一個職工的姓和名分成兩列存放(FIRST_NAME和LAST_NAME),現在要查詢一個叫比爾.柯林頓(Bill
Cliton)的職工。
下面是一個採用聯接查詢的SQL語句,
select
*
from
employss
where
first_name||''||last_name
='Beill
Cliton';
上面這條語句完全可以查詢出是否有Bill
Cliton這個員工,但是這里需要注意,系統優化器對基於last_name創建的索引沒有使用。
當採用下面這種SQL語句的編寫,Oracle系統就可以採用基於last_name創建的索引。
***
where
first_name
='Beill'
and
last_name
='Cliton';
.
帶通配符(%)的like語句
同樣以上面的例子來看這種情況。目前的需求是這樣的,要求在職工表中查詢名字中包含cliton的人。可以採用如下的查詢SQL語句:
select
*
from
employee
where
last_name
like
'%cliton%';
這里由於通配符(%)在搜尋詞首出現,所以Oracle系統不使用last_name的索引。在很多情況下可能無法避免這種情況,但是一定要心中有底,通配符如此使用會降低查詢速度。然而當通配符出現在字元串其他位置時,優化器就能利用索引。在下面的查詢中索引得到了使用:
select
*
from
employee
where
last_name
like
'c%';
4.
Order
by語句
ORDER
BY語句決定了Oracle如何將返回的查詢結果排序。Order
by語句對要排序的列沒有什麼特別的限制,也可以將函數加入列中(象聯接或者附加等)。任何在Order
by語句的非索引項或者有計算表達式都將降低查詢速度。
仔細檢查order
by語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫order
by語句以使用索引,也可以為所使用的列建立另外一個索引,同時應絕對避免在order
by子句中使用表達式。
5.
NOT
我們在查詢時經常在where子句使用一些邏輯表達式,如大於、小於、等於以及不等於等等,也可以使用and(與)、or(或)以及not(非)。NOT可用來對任何邏輯運算符號取反。下面是一個NOT子句的例子:
...
where
not
(status
='VALID')
如果要使用NOT,則應在取反的短語前面加上括弧,並在短語前面加上NOT運算符。NOT運算符包含在另外一個邏輯運算符中,這就是不等於(<>)運算符。換句話說,即使不在查詢where子句中顯式地加入NOT詞,NOT仍在運算符中,見下例:
...
where
status
<>'INVALID';
對這個查詢,可以改寫為不使用NOT:
select
*
from
employee
where
salary<3000
or
salary>3000;
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。

4. 伺服器中用sql查詢分析器查詢一條語句花的時間要2分鍾才出結果,怎麼解決讓其更快

在sql的查詢分析器界面上選擇顯示執行計劃,看看這么長的時間都花在什麼地方了,然後備物或再對症下葯。再有就是你的sql語句的選擇性好不好,返回的結果集數據量大不大,有沒有設計索引,索引有沒有起到作用等都會有影響。
如果有索引但是索引沒有起到預期的效果,可以看看索引的統計信息是仿伍不是太老了。建議刪除索引重新建螞物立。

5. 如何提高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' // oracle總有的是substr函數。
select id from t where datediff(day,createdate,'2005-11-30')=0 //查過了確實沒有datediff函數。
應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1' //
oracle 中時間應該把char 轉換成 date 如: createdate >= to_date('2005-11-30','yyyy-mm-dd')
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.盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

6. 如何讓SQL運行得更快

一、不合理的索引設計
----例:表record有620000行,試看在不同的索引下,下面幾個 SQL的運行情況:
---- 1.在date上建有一非個群集索引
select count(*) from record where date >
'19991201' and date < '19991214'and amount >
2000 (25秒)
select date,sum(amount) from record group by date
(55秒)
select count(*) from record where date >
'19990901' and place in ('BJ','SH') (27秒)
---- 分析:
----date上有大量的重復值,在非群集索引下做慧,數據在物理上隨機存放在數據頁上,在
范圍查找時,必須執行一次表掃描才能找到這一范圍內的全部行。
---- 2.在date上的一個群集索引
select count(*) from record where date >
'19991201' and date < '19991214' and amount >
2000 (14秒)
select date,sum(amount) from record group by date
(28秒)
select count(*) from record where date >
'19990901' and place in ('BJ','SH')(14秒)
---- 分析:
---- 在群集索引下,數據在物理上按順序在數據頁上,重復值也排列在一起,因而在范
圍查找時,可以先找到這個范圍的起末點,且只在這個范圍內掃描數據頁,避免了大范
圍掃描,提高了查詢速度。
---- 3.在place,date,amount上的組合索引
select count(*) from record where date >
'19991201' and date < '19991214' and amount >
2000 (26秒)
select date,sum(amount) from record group by date
(27秒)
select count(*) from record where date >
'19990901' and place in ('BJ', 'SH')(< 1秒)
---- 分析:
---- 這是一個不很合余胡鏈理的組合索引,因為它的前導列是place,第一和第二條SQL沒有引
用place,因此也沒有利用上索引;第三個SQL使用了place,且引用的所有列都包含在組
合索引中,形成了索引覆蓋,所以它的速度是非常快的。
---- 4.在date,place,amount上的組合索引
select count(*) from record where date >
'19991201' and date < '19991214' and amount >
2000(< 1秒)
select date,sum(amount) from record group by date
(11秒)
select count(*) from record where date >
'19990901' and place in ('BJ','SH')(< 1秒)
---- 分析:
---- 這是一個合理的組合索引。它將date作為前導列,使每個SQL都可以利用索引,並
且在第一和第三個SQL中形成豎孫了索引覆蓋,因而性能達到了最優。
---- 5.總結:
---- 預設情況下建立的索引是非群集索引,但有時它並不是最佳的;合理的索引設計要
建立在對各種查詢的分析和預測上。一般來說:
---- ①.有大量重復值、且經常有范圍查詢
(between, >,< ,>=,< =)和order by
、group by發生的列,可考慮建立群集索引;
---- ②.經常同時存取多列,且每列都含有重復值可考慮建立組合索引;
---- ③.組合索引要盡量使關鍵查詢形成索引覆蓋,其前導列一定是使用最頻繁的列。 二、不充份的連接條件:
---- 例:表card有7896行,在card_no上有一個非聚集索引,表account有191122行,在
account_no上有一個非聚集索引,試看在不同的表連接條件下,兩個SQL的執行情況: select sum(a.amount) from account a,
card b where a.card_no = b.card_no(20秒)
---- 將SQL改為:
select sum(a.amount) from account a,
card b where a.card_no = b.card_no and a.
account_no=b.account_no(< 1秒)
---- 分析:
---- 在第一個連接條件下,最佳查詢方案是將account作外層表,card作內層表,利用
card上的索引,其I/O次數可由以下公式估算為:
---- 外層表account上的22541頁+(外層表account的191122行*內層表card上對應外層
表第一行所要查找的3頁)=595907次I/O
---- 在第二個連接條件下,最佳查詢方案是將card作外層表,account作內層表,利用
account上的索引,其I/O次數可由以下公式估算為:
---- 外層表card上的1944頁+(外層表card的7896行*內層表account上對應外層表每一
行所要查找的4頁)= 33528次I/O
---- 可見,只有充份的連接條件,真正的最佳方案才會被執行。
---- 總結:
---- 1.多表操作在被實際執行前,查詢優化器會根據連接條件,列出幾組可能的連接方
案並從中找出系統開銷最小的最佳方案。連接條件要充份考慮帶有索引的表、行數多的
表;內外表的選擇可由公式:外層表中的匹配行數*內層表中每一次查找的次數確定,乘
積最小為最佳方案。
---- 2.查看執行方案的方法-- 用set showplanon,打開showplan選項,就可以看到連
接順序、使用何種索引的信息;想看更詳細的信息,需用sa角色執行dbcc(3604,310,30
2)。
三、不可優化的where子句
---- 1.例:下列SQL條件語句中的列都建有恰當的索引,但執行速度卻非常慢:
select * from record where
substring(card_no,1,4)='5378'(13秒)
select * from record where
amount/30< 1000(11秒)
select * from record where
convert(char(10),date,112)='19991201'(10秒)
---- 分析:
---- where子句中對列的任何操作結果都是在SQL運行時逐列計算得到的,因此它不得不
進行表搜索,而沒有使用該列上面的索引;如果這些結果在查詢編譯時就能得到,那麼
就可以被SQL優化器優化,使用索引,避免表搜索,因此將SQL重寫成下面這樣:
select * from record where card_no like
'5378%'(< 1秒)
select * from record where amount
< 1000*30(< 1秒)
select * from record where date= '1999/12/01'
(< 1秒)
---- 你會發現SQL明顯快起來!
---- 2.例:表stuff有200000行,id_no上有非群集索引,請看下面這個SQL:
select count(*) from stuff where id_no in('0','1')
(23秒)
---- 分析:
---- where條件中的'in'在邏輯上相當於'or',所以語法分析器會將in ('0','1')轉化
為id_no ='0' or id_no='1'來執行。我們期望它會根據每個or子句分別查找,再將結果
相加,這樣可以利用id_no上的索引;但實際上(根據showplan),它卻採用了"OR策略"
,即先取出滿足每個or子句的行,存入臨時資料庫的工作表中,再建立唯一索引以去掉
重復行,最後從這個臨時表中計算結果。因此,實際過程沒有利用id_no上索引,並且完
成時間還要受tempdb資料庫性能的影響。
---- 實踐證明,表的行數越多,工作表的性能就越差,當stuff有620000行時,執行時
間竟達到220秒!還不如將or子句分開:
select count(*) from stuff where id_no='0'
select count(*) from stuff where id_no='1'
---- 得到兩個結果,再作一次加法合算。因為每句都使用了索引,執行時間只有3秒,
在620000行下,時間也只有4秒。或者,用更好的方法,寫一個簡單的存儲過程:
create proc count_stuff as
declare @a int
declare @b int
declare @c int
declare @d char(10)
begin
select @a=count(*) from stuff where id_no='0'
select @b=count(*) from stuff where id_no='1'
end
select @c=@a+@b
select @d=convert(char(10),@c)
print @d

7. 查詢的SQL語句怎麼寫才能提高查詢效率

這是SQL語句優化的問題了。網上好多類似的文章,非常全面。
個人覺得比較常用的是:
SQL語句查詢中經常用到的欄位建索引,這樣可以非常明顯的提升查詢速度。
FROM表的順序,大表在前,小表在後,因為檢索的順序從後往前。
WHERE, WHERE A.COLUMN = B.COLUMN,把小表的欄位放在後邊(B表),大表在前。
固定值查詢的放在後邊 COLUMN = '1'這種。因為這個也是從後往前的順序。
如果有(NOT) IN (SELECT ...) 盡量避免,因為IN裡面也是一個大的查詢,使用 (NOT) EXISTS的語法代替。
還有UNION和UNION ALL,多表聯合,UNION的作用是可以去掉重復,如果多表沒有重復數據,使用UNION ALL效率也會大大提高。

8. 怎樣提升SQL語句的查詢速度

1.選擇最有效率的表名順序。ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最後的表(基礎表 driving table)將被最先處理. 在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
2.WHERE子句中的連接順序。ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
3.SELECT子句中盡量避免使用 『* 』。
4.使用DECODE函數來減少處理時間。
5.查詢結果能不排序就不排序。盡量不用Order by,distinct,union,MINUS,INTERSECT。
6.用表連接代替子查詢in。
7.用索引提高查詢效率。但是索引不能隨便用,還要搞清楚每種索引適用的情況,比如B*索引、復合索引、函數索引、bitmap索引等。雖然使用索引能得到查詢效率的提高,但是也必須注意到它的代價. 索引需要空間來存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改. 這意味著每條記錄的INSERT , DELETE , UPDATE將為此多付出幾 次的磁碟I/O,因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢。
8.不能再索引列上適用not、<>、is null、not is null、做四則運算,否則索引會被抑制,不起作用,變成全表掃描。
9.用>=替代>。比如SELECT * FROM S WHERE ID>=4效率SELECT * FROM S WHERE ID>3高。兩者的區別在於, 前者DBMS將直接跳到第一個ID等於4的記錄,而後者將首先定位到ID=3的記錄並且向前掃描到第一個DEPT大於3的記錄。
10.如果表的數據量很大,可以為該表建分區。經常使用的子查詢可以建成視圖。
.
.
.
.
.
.
.
.

9. 怎樣讓mysql中sql語句性能最優

一、MySQL資料庫有幾個配置選項可以幫助我們及時捕獲低效SQL語句

1,slow_query_log
這個參數設置歲源為ON,可以捕獲執行時間超過一定數值的SQL語句。

2,long_query_time
當SQL語句執行時間超過此數值時,就會被記錄到日誌中,建議設置為1或者更短。

3,slow_query_log_file
記錄日誌的文件名。

4,log_queries_not_using_indexes
這個參數設置為ON,可以捕獲到所有未使用索引的SQL語句,盡管這個SQL語句有可能執行得挺快。

二、檢測mysql中sql語句的效率的方法

1、通過查詢日誌
(1)、Windows下開啟MySQL慢查詢
MySQL在Windows系統中的配置文件一般是是my.ini找到橋雀李[mysqld]下面加上
代碼如下
log-slow-queries = F:/MySQL/log/mysqlslowquery。log
long_query_time = 2

(2)、Linux下啟用MySQL慢查詢
MySQL在Windows系統中的配置文件一般是是my.cnf找到[mysqld]下面加上
代敏遲碼如下
log-slow-queries=/data/mysqldata/slowquery。log
long_query_time=2

10. 這種sql語句怎麼優化 查詢更快

你這個單表優化,基本就是靠加索引解決,既然是id列,應該建主鍵了吧?主鍵相當於索引了啊,不拍攔應該慢了。

如果橡譽是mysql資料庫,可以在sql語句前面,加上explain,這個是mysql的查詢分析器,梁賀段根據返回結果判斷如何優化sql語句