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

sql語句要做某些必要擴充

發布時間: 2023-01-06 21:24:52

sql查詢語句

SQL查詢語句大全

SQL語句無論是種類還是數量都是繁多的,很多語句也是經常要用到的,SQL查詢語句就是一個典型的例子,無論是高級查詢還是低級查詢,SQL查詢語句的需求是最頻繁的。那麼SQL查詢語句有哪些?下面跟我一起來看看吧!

一、簡單查詢語句

1. 查看錶結構

SQL>DESC emp;

2. 查詢所有列

SQL>SELECT * FROM emp;

3. 查詢指定列

SQL>SELECT empmo, ename, mgr FROM emp;

SQL>SELECT DISTINCT mgr FROM emp; 只顯示結果不同的項

4. 查詢指定行

SQL>SELECT * FROM emp WHERE job='CLERK';

5. 使用算術表達式

SQL>SELECT ename, sal*13+nvl(comm,0) FROM emp;

nvl(comm,1)的意思是,如果comm中有值,則nvl(comm,1)=comm; comm中無值,則nvl(comm,1)=0。

SQL>SELECT ename, sal*13+nvl(comm,0) year_sal FROM emp; (year_sal為別名,可按別名排序)

SQL>SELECT * FROM emp WHERE hiredate>'01-1月-82';

6. 使用like操作符(%,_)

%表示一個或多個字元,_表示一個字元,[charlist]表示字元列中的任何單一字元,[^charlist]或者[!charlist]不在字元列中的任何單一字元。

SQL>SELECT * FROM emp WHERE ename like 'S__T%';

7. 在where條件中使用In

SQL>SELECT * FROM emp WHERE job IN ('CLERK','ANALYST');

8. 查詢欄位內容為空/非空的語句

SQL>SELECT * FROM emp WHERE mgr IS/IS NOT NULL;

9. 使用邏輯操作符號

SQL>SELECT * FROM emp WHERE (sal>500 or job='MANAGE') and ename like 'J%';

10. 將查詢結果按欄位的值進行排序

SQL>SELECT * FROM emp ORDER BY deptno, sal DESC; (按部門升序,並按薪酬降序)

二、復雜查詢

1. 數據分組(max,min,avg,sum,count)

SQL>SELECT MAX(sal),MIN(age),AVG(sal),SUM(sal) from emp;

SQL>SELECT * FROM emp where sal=(SELECT MAX(sal) from emp));

SQL>SELEC COUNT(*) FROM emp;

2. group by(用於對查詢結果的分組統計) 和 having子句(用於限制分組顯示結果)

SQL>SELECT deptno,MAX(sal),AVG(sal) FROM emp GROUP BY deptno;

SQL>SELECT deptno, job, AVG(sal),MIN(sal) FROM emp group by deptno,job having AVG(sal)<2000;

對於數據分組的總結:

a. 分組函數只能出現在選擇列表、having、order by子句中(不能出現在where中)

b. 如果select語句中同時包含有group by, having, order by,那麼它們的順序是group by, having, order by。

c. 在選擇列中如果有列、表達式和分組函數,那麼這些列和表達式必須出現在group by子句中,否則就是會出錯。

使用group by不是使用having的前提條件。

3. 多表查詢

SQL>SELECT e.name,e.sal,d.dname FROM emp e, dept d WHERE e.deptno=d.deptno order by d.deptno;

SQL>SELECT e.ename,e.sal,s.grade FROM emp e,salgrade s WHER e.sal BETWEEN s.losal AND s.hisal;

4. 自連接(指同一張表的連接查詢)

SQL>SELECT er.ename, ee.ename mgr_name from emp er, emp ee where er.mgr=ee.empno;

5. 子查詢(嵌入到其他sql語句中的select語句,也叫嵌套查詢)

5.1 單行子查詢

SQL>SELECT ename FROM emp WHERE deptno=(SELECT deptno FROM emp where ename='SMITH');查詢表中與smith同部門的人員名字。因為返回結果只有一行,所以用「=」連接子查詢語句

5.2 多行子查詢

SQL>SELECT ename,job,sal,deptno from emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno=10);查詢表中與部門號為10的工作相同的員工的姓名、工作、薪水、部門號。因為返回結果有多行,所以用「IN」連接子查詢語句。

in與exists的區別: exists() 後面的子查詢被稱做相關子查詢,它是不返回列表的值的。只是返回一個ture或false的結果,其運行方式是先運行主查詢一次,再去子查詢里查詢與其對 應的結果。如果是ture則輸出,反之則不輸出。再根據主查詢中的每一行去子查詢里去查詢。in()後面的子查詢,是返回結果集的,換句話說執行次序和 exists()不一樣。子查詢先產生結果集,然後主查詢再去結果集里去找符合要求的欄位列表去。符合要求的輸出,反之則不輸出。

5.3 使用ALL

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ALL (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MAX(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的所有員工工資都高的員工的姓名、薪水和部門號。以上兩個語句在功能上是一樣的,但執行效率上,函數會高 得多。

5.4 使用ANY

SQL>SELECT ename,sal,deptno FROM emp WHERE sal> ANY (SELECT sal FROM emp WHERE deptno=30);或SQL>SELECT ename,sal,deptno FROM emp WHERE sal> (SELECT MIN(sal) FROM emp WHERE deptno=30);查詢工資比部門號為30號的任意一個員工工資高(只要比某一員工工資高即可)的員工的姓名、薪水和部門號。以上兩個語句在功能上是 一樣的,但執行效率上,函數會高得多。

5.5 多列子查詢

SQL>SELECT * FROM emp WHERE (job, deptno)=(SELECT job, deptno FROM emp WHERE ename='SMITH');

5.6 在from子句中使用子查詢

SQL>SELECT emp.deptno,emp.ename,emp.sal,t_avgsal.avgsal FROM emp,(SELECT emp.deptno,avg(emp.sal) avgsal FROM emp GROUP BY emp.deptno) t_avgsal where emp.deptno=t_avgsal.deptno AND emp.sal>t_avgsal.avgsal ORDER BY emp.deptno;

5.7 分頁查詢

資料庫的每行數據都有一個對應的行號,稱為rownum.

SQL>SELECT a2.* FROM (SELECT a1.*, ROWNUM rn FROM (SELECT * FROM emp ORDER BY sal) a1 WHERE ROWNUM<=10) a2="" where="" rn="">=6;

指定查詢列、查詢結果排序等,都只需要修改最里層的子查詢即可。

5.8 用查詢結果創建新表

SQL>CREATE TABLE mytable (id,name,sal,job,deptno) AS SELECT empno,ename,sal,job,deptno FROM emp;

5.9 合並查詢(union 並集, intersect 交集, union all 並集+交集, minus差集)

SQL>SELECT ename, sal, job FROM emp WHERE sal>2500 UNION(INTERSECT/UNION ALL/MINUS) SELECT ename, sal, job FROM emp WHERE job='MANAGER';

合並查詢的執行效率遠高於and,or等邏輯查詢。

5.10 使用子查詢插入數據

SQL>CREATE TABLE myEmp(empID number(4), name varchar2(20), sal number(6), job varchar2(10), dept number(2)); 先建一張空表;

SQL>INSERT INTO myEmp(empID, name, sal, job, dept) SELECT empno, ename, sal, job, deptno FROM emp WHERE deptno=10; 再將emp表中部門號為10的數據插入到新表myEmp中,實現數據的批量查詢。

5.11 使用了查詢更新表中的數據

SQL>UPDATE emp SET(job, sal, comm)=(SELECT job, sal, comm FROM emp where ename='SMITH') WHERE ename='SCOTT';

簡介

SQL語言1974年由Boyce和Chamberlin提出,並首先在IBM公司研製的關系資料庫系統SystemR上實現。由於它具有功能豐富、使用方便靈活、語言簡潔易學等突出的優點,深受計算機工業界和計算機用戶的歡迎。1980年10月,經美國國家標准局(ANSI)的資料庫委員會X3H2批准,將SQL作為關系資料庫語言的美國標准,同年公布了標准SQL,此後不久,國際標准化組織(ISO)也作出了同樣的決定。

SQL從功能上可以分為3部分:數據定義、數據操縱和數據控制。

SQL的核心部分相當於關系代數,但又具有關系代數所沒有的許多特點,如聚集、資料庫更新等。它是一個綜合的、通用的、功能極強的關系資料庫語言。其特點是:

1、數據描述、操縱、控制等功能一體化。

2、兩種使用方式,統一的語法結構。SQL有兩種使用方式。一是聯機交互使用,這種方式下的SQL實際上是作為自含型語言使用的。另一種方式是嵌入到某種高級程序設計語言(如C語言等)中去使用。前一種方式適合於非計算機專業人員使用,後一種方式適合於專業計算機人員使用。盡管使用方式不向,但所用語言的語法結構基本上是一致的。

3、高度非過程化。SQL是一種第四代語言(4GL),用戶只需要提出「干什麼」,無須具體指明「怎麼干」,像存取路徑選擇和具體處理操作等均由系統自動完成。

4、語言簡潔,易學易用。盡管SQL的'功能很強,但語言十分簡潔,核心功能只用了9個動詞。SQL的語法接近英語口語,所以,用戶很容易學習和使用。

功能

SQL具有數據定義、數據操縱、和數據控制的功能。

1、SQL數據定義功能:能夠定義資料庫的三級模式結構,即外模式、全局模式和內模式結構。在SQL中,外模式又叫做視圖(View),全局模式簡稱模式(Schema),內模式由系統根據資料庫模式自動實現,一般無需用戶過問。

2、SQL數據操縱功能:包括對基本表和視圖的數據插入、刪除和修改,特別是具有很強的數據查詢功能。

3、SQL的數據控制功能:主要是對用戶的訪問許可權加以控制,以保證系統的安全性。

語句結構

結構化查詢語言包含6個部分:

1、數據查詢語言(DQL: Data Query Language):其語句,也稱為「數據檢索語句」,用以從表中獲得數據,確定數據怎樣在應用程序給出。保留字SELECT是DQL(也是所有SQL)用得最多的動詞,其他DQL常用的保留字有WHERE,ORDER BY,GROUP BY和HAVING。這些DQL保留字常與其它類型的SQL語句一起使用。

2、數據操作語言(DML:Data Manipulation Language):其語句包括動詞INSERT、UPDATE和DELETE。它們分別用於添加、修改和刪除。

3、事務控制語言(TCL):它的語句能確保被DML語句影響的表的所有行及時得以更新。包括COMMIT(提交)命令、SAVEPOINT(保存點)命令、ROLLBACK(回滾)命令。

4、數據控制語言(DCL):它的語句通過GRANT或REVOKE實現許可權控制,確定單個用戶和用戶組對資料庫對象的訪問。某些RDBMS可用GRANT或REVOKE控制對表單個列的訪問。

5、數據定義語言(DDL):其語句包括動詞CREATE,ALTER和DROP。在資料庫中創建新表或修改、刪除表(CREATE TABLE 或 DROP TABLE);為表加入索引等。

6、指針控制語言(CCL):它的語句,像DECLARE CURSOR,FETCH INTO和UPDATE WHERE CURRENT用於對一個或多個表單獨行的操作。

語言特點

SQL風格統一

SQL可以獨立完成資料庫生命周期中的全部活動,包括定義關系模式、錄入數據、建立資料庫、査詢、更新、維護、資料庫重構、資料庫安全性控制等一系列操作,這就為資料庫應用系統開發提供了良好的環境,在資料庫投入運行後,還可根據需要隨時逐步修改模式,且不影響資料庫的運行,從而使系統具有良好的可擴充性。

高度非過程化

非關系數據模型的數據操縱語言是面向過程的語言,用其完成用戶請求時,必須指定存取路徑。而用SQL進行數據操作,用戶只需提出「做什麼」,而不必指明「怎麼做」,因此用戶無須了解存取路徑,存取路徑的選擇以及SQL語句的操作過程由系統自動完成。這不但大大減輕了用戶負擔,而且有利於提高數據獨立性。

面向集合的操作方式

SQL採用集合操作方式,不僅查找結果可以是元組的集合,而且一次插入、刪除、更新操作的對象也可以是元組的集合。

以同一種語法結構提供兩種使用方式

SQL既是自含式語言,又是嵌入式語言。作為自含式語言,它能夠獨立地用於聯機交互的使用方式,用戶可以在終端鍵盤上直接輸入SQL命令對資料庫進行操作。作為嵌入式語言,SQL語句能夠嵌入到高級語言(如C、C#、JAVA)程序中,供程序員設計程序時使用。而在兩種不同的使用方式下,SQL的語法結構基本上是一致的。這種以統一的語法結構提供兩種不同的操作方式,為用戶提供了極大的靈活性與方便性。

語言簡潔,易學易用

SQL功能極強,但由於設計巧妙,語言十分簡潔,完成數據定義、數據操縱、數據控制的核心功能只用了9個動詞:CREATE、ALTER、DROP、SELECT、INSERT、UPDATE、DELETE、GRANT、REVOKE。且SQL語言語法簡單,接近英語口語,因此容易學習,也容易使用。

;

❷ 優化SQL有什麼方法

在資料庫應用系統中編寫可執行的SQL語句可以有多種方式實現,但哪一條是最佳方案卻難以確定。為了解決這一問題,有必要對SQL實施優化。簡單地說,SQL語句的優化就是將性能低下的SQL語句轉換成達到同樣目的的性能更好的SQL語句。

優化SQL語句的原因

資料庫系統的生命周期可以分成: 設計、開發和成品三個階段。在設計階段進行優化的成本最低,收益最大。在成品階段進行優化的成本最高,收益最小。如果將一個資料庫系統比喻成一座樓房,在樓房建好後進行矯正往往成本很高而收效很小(甚至可能根本無法矯正),而在樓房設計、生產階段控制好每塊磚瓦的質量就能達到花費小而見效高的目的。

為了獲得最大效益,人們常需要對資料庫進行優化。資料庫的優化通常可以通過對網路、硬體、操作系統、資料庫參數和應用程序的優化來進行。根據統計,對網路、硬體、操作系統、資料庫參數進行優化所獲得的性能提升全部加起來只佔資料庫應用系統性能提升的40%左右,其餘60%的系統性能提升全部來自對應用程序的優化。許多優化專家甚至認為對應用程序的優化可以得到80%的系統性能提升。因此可以肯定,通過優化應用程序來對資料庫系統進行優化能獲得更大的收益。

對應用程序的優化通常可分為兩個方面: 源代碼的優化和SQL語句的優化。由於涉及到對程序邏輯的改變,源代碼的優化在時間成本和風險上代價很高(尤其是對正在使用中的系統進行優化) 。另一方面,源代碼的優化對資料庫系統性能的提升收效有限,因為應用程序對資料庫的操作最終要表現為SQL語句對資料庫的操作。

對SQL語句進行優化有以下一些直接原因:

1. SQL語句是對資料庫(數據) 進行操作的惟一途徑,應用程序的執行最終要歸結為SQL語句的執行,SQL語句的效率對資料庫系統的性能起到了決定性的作用。

2. SQL語句消耗了70%~90%的資料庫資源。

3. SQL語句獨立於程序設計邏輯,對SQL語句進行優化不會影響程序邏輯,相對於對程序源代碼的優化,對SQL語句的優化在時間成本和風險上的代價都很低。

4. SQL語句可以有不同的寫法,不同的寫法在性能上的差異可能很大。

5. SQL語句易學,難精通。SQL語句的性能往往同實際運行系統的資料庫結構、記錄數量等有關,不存在普遍適用的規律來提升性能。

傳統的優化方法

SQL程序人員在傳統上採用手工重寫來對SQL語句進行優化。這主要依靠DBA或資深程序員對SQL語句執行計劃的分析,依靠經驗,嘗試重寫SQL語句,然後對結果和性能進行比較以試圖找到性能較佳的SQL語句。這種做法存在著以下不足:

1. 無法找出SQL語句的所有可能寫法。很可能花費了大量的時間也無法找到性能較佳的SQL語句。即便找到了某個性能較佳的SQL語句也無法知道是否存在性能更好的寫法。

2. 非常依賴於人的經驗,經驗的多寡往往決定了優化後SQL語句的性能。

3. 非常耗時間。重寫-->校驗正確性-->比較性能,這一循環過程需要大量的時間。

根據傳統的SQL優化工具的功能,人們一般將優化工具分為以下三代產品:

第一代的SQL優化工具是執行計劃分析工具。這類工具對輸入的SQL語句從資料庫提取執行計劃,並解釋執行計劃中關鍵字的含義。

第二代的SQL優化工具只能提供增加索引的建議,它通過對輸入的SQL語句的執行計劃的分析來產生是否要增加索引的建議。這類工具存在著致命的缺點——只分析了一條SQL語句就得出增加某個索引的結論,根本不理會(實際上也無法評估到)增加的索引對整體資料庫系統性能的影響。

第三代工具是利用人工智慧實現自動SQL優化。

人工智慧自動SQL優化

隨著人工智慧技術的發展和在資料庫優化領域應用的深入,在20世紀90年代末優化技術取得了突破性的進展,出現了人工智慧自動SQL優化。人工智慧自動SQL優化的本質就是藉助人工智慧技術,自動對SQL語句進行重寫,找到性能最好的等效SQL語句。LECCO SQL Expert就採用了這種人工智慧技術,其SQL Expert支持Oracle、Sybase、MS SQL Server和IBM DB2資料庫平台。其突出特點是自動優化SQL語句。除此以外,還可以以人工智慧知識庫「反饋式搜索引擎」來重寫SQL語句,並找出所有等效的SQL語句及可能的執行計劃,通過測試運行為應用程序和資料庫自動找到性能最好的SQL語句,提供微秒級的計時; 能夠優化Web應用程序和有大量用戶的在線事務處理中運行時間很短的SQL語句; 能通過比較源SQL和待選SQL的不同之處,為開發人員提供「邊做邊學式訓練」,迅速提高開發人員的SQL編程技能等等。

該工具針對資料庫應用的開發和維護階段提供了數個特別的模塊:SQL語法優化器、PL/SQL集成化開發調試環境(IDE)、掃描器、資料庫監視器等。其核心模塊之一「SQL 語法優化器」的工作原理大致如下:輸入一條源SQL語句,「人工智慧反饋式搜索引擎」對輸入的SQL語句結合檢測到的資料庫結構和索引進行重寫,產生N條等效的SQL語句輸出,產生的N條等效SQL語句再送入「人工智慧反饋式搜索引擎」進行重寫,直至無法產生新的輸出或搜索限額滿,接下來對輸出的SQL語句進行過濾,選出具有不同執行計劃的SQL語句(不同的執行計劃意味著不同的執行效率),最後,對得到的SQL語句進行批量測試,找出性能最好的SQL語句(參見下圖)。

圖 人工智慧自動SQL優化示意圖

LECCO SQL Expert不僅能夠找到最佳的SQL語句,它所提供的「邊做邊學式訓練」還能夠教會開發人員和資料庫管理員如何寫出性能最好的SQL語句。LECCO SQL Expert的SQL語句自動優化功能使SQL的優化變得極其簡單,只要能夠寫出SQL語句,它就能幫開發人員找到最好性能的寫法。

小 結

SQL語句是資料庫應用中一個非常關鍵的部分,它執行性能的高低直接影響著應用程序的運行效率。正因為如此,人們在SQL語句的優化上投入了很大的精力,出現了許多SQL語句優化工具。隨著人工智慧等相關技術的日益成熟, 肯定還會有更多更好的工具出現,這將會給開發人員提供更多的幫助。

❸ 如何進行SQL性能優化

這里分享下mysql優化的幾種方法。

1、首先在打開的軟體中,需要分別為每一個表創建 InnoDB FILE的文件。

❹ sql語句優化怎麼做的,建索引的時候要考慮什麼

1、表的主鍵、外鍵必須有索引;
2、數據量超過300的表應該有索引;
3、經常與其他表進行連接的表,在連接欄位上應該建立索引;
4、經常出現在Where子句中的欄位,特別是大表的欄位,應該建立索引;
5、索引應該建在選擇性高的欄位上;
6、索引應該建在小欄位上,對於大的文本欄位甚至超長欄位,不要建索引;
7、復合索引的建立需要進行仔細分析;盡量考慮用單欄位索引代替:
A、正確選擇復合索引中的主列欄位,一般是選擇性較好的欄位;
B、復合索引的幾個欄位是否經常同時以AND方式出現在Where子句中?單欄位查詢是否極少甚至沒有?如果是,則可以建立復合索引;否則考慮單欄位索引;
C、如果復合索引中包含的欄位經常單獨出現在Where子句中,則分解為多個單欄位索引;
D、如果復合索引所包含的欄位超過3個,那麼仔細考慮其必要性,考慮減少復合的欄位;
E、如果既有單欄位索引,又有這幾個欄位上的復合索引,一般可以刪除復合索引;
8、頻繁進行數據操作的表,不要建立太多的索引;
9、刪除無用的索引,避免對執行計劃造成負面影響;
以上是一些普遍的建立索引時的判斷依據。一言以蔽之,索引的建立必須慎重,對每個索引的必要性都應該經過仔細分析,要有建立的依據。因為太多的索引與不充分、不正確的索引對性能都毫無益處:在表上建立的每個索引都會增加存儲開銷,索引對於插入、刪除、更新操作也會增加處理上的開銷。另外,過多的復合索引,在有單欄位索引的情況下,一般都是沒有存在價值的;相反,還會降低數據增加刪除時的性能,特別是對頻繁更新的表來說,負面影響更大。

❺ 請簡單說明SQL語句書可以提高執行效率的5種需要注意的書寫方法。

之前收集的一些資料僅供參考, 不一定完全正確... 有錯誤望指正

1、操作符號: NOT IN操作符
此操作是強列推薦不使用的,因為它不能應用表的索引。推薦方案:用NOT EXISTS 或(外連接+判斷為空)方案代替 "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", "LIKE '%500'",因為他們不走索引全是表掃描。NOT IN會多次掃描表,使用EXISTS、NOT EXISTS、IN、LEFT OUTER JOIN來替代,特別是左連接,而Exists比IN更快,最慢的是NOT操作. 如果列的值含有空,以前它的索引不起作用,現在2000的優化器能夠處理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能優化她,而"<>"等還是不能優化,用不到索引。

2、注意union和union all的區別。union比union all多做了一步distinct操作。能用union all的情況下盡量不用union。

3、查詢時盡量不要返回不需要的行、列。另外在多表連接查詢時,盡量改成連接查詢,少用子查詢。。

4、盡量少用視圖,它的效率低。對視圖操作比直接對表操作慢,可以用存儲過程來代替它。特別的是不要用視圖嵌套,嵌套視圖增加了尋找原始資料的難度。
我們看視圖的本質:它是存放在伺服器上的被優化好了的已經產生了查詢規劃的SQL。對單個表檢索數據時,不要使用指向多個表的視圖,
直接從表檢索或者僅僅包含這個表的視圖上讀,否則增加了不必要的開銷,查詢受到干擾.為了加快視圖的查詢,MsSQL增加了視圖索引的功能。

5、創建合理的索引,對於插入或者修改比較頻繁的表,盡量慎用索引。因為如果表中存在索引,插入和修改時也會引起全表掃描。
索引一般使用於where後經常用作條件的欄位上。

6、在表中定義欄位或者存儲過程、函數中定義參數時,將參數的大小設置為合適即可,勿設置太大。這樣開銷很大。

7、Between在某些時候比IN速度更快,Between能夠更快地根據索引找到范圍。用查詢優化器可見到差別。
select * from chineseresume where title in ('男','女')
Select * from chineseresume where between '男' and '女'是一樣的。由於in會在比較多次,所以有時會慢些。

8、在必要是對全局或者局部臨時表創建索引,有時能夠提高速度,但不是一定會這樣,因為索引也耗費大量的資源。他的創建同是實際表一樣。

9、WHERE後面的條件順序影響
WHERE子句後面的條件順序對大數據量表的查詢會產生直接的影響,如
Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1
Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'
以上兩個SQL中dy_dj(電壓等級)及xh_bz(銷戶標志)兩個欄位都沒進行索引,所以執行的時候都是全表掃描,如果dy_dj = '1KV以下'條件在記錄集內比率為99%,而xh_bz=1的比率只為0.5%,在進行第一條SQL的時候99%條記錄都進行dy_dj及xh_bz的比較,而在進行第二條SQL的時候0.5%條記錄都進行dy_dj及xh_bz的比較,以此可以得出第二條SQL的CPU佔用率明顯比第一條低。所以盡量將范圍小的條件放在前面。。

10、用OR的字句可以分解成多個查詢,並且通過UNION 連接多個查詢。他們的速度只同是否使用索引有關,如果查詢需要用到聯合索引,用 UNION all執行的效率更高.多個OR的字句沒有用到索引,改寫成UNION的形式再試圖與索引匹配。一個關鍵的問題是否用到索引。

11、沒有必要時不要用DISTINCT和ORDER BY,這些動作可以改在客戶端執行。它們增加了額外的開銷。這同UNION和UNION ALL一樣的道理。

12、使用in時,在IN後面值的列表中,將出現最頻繁的值放在最前面,出現得最少的放在最後面,這樣可以減少判斷的次數

13、當用SELECT INTO時,它會鎖住系統表(sysobjects,sysindexes等等),阻塞其他的連接的存取。創建臨時表時用顯示聲明語句,在另一個連接中SELECT * from sysobjects可以看到 SELECT INTO 會鎖住系統表, Create table 也會鎖系統表(不管是臨時表還是系統表)。所以千萬不要在事物內使用它!!!這樣的話如果是經常要用的臨時表請使用實表,或者臨時表變數。

14、一般在GROUP BY和HAVING字句之前就能剔除多餘的行,所以盡量不要用它們來做剔除行的工作。他們的執行順序應該如下最優:select 的Where字句選擇所有合適的行,Group By用來分組個統計行,Having字句用來剔除多餘的分組。這樣Group By和Having的開銷小,查詢快.對於大的數據行進行分組和Having十分消耗資源。如果Group BY的目的不包括計算,只是分組,那麼用Distinct更快

15、一次更新多條記錄比分多次更新每次一條快,就是說批處理好

16、慎用臨時表,臨時表存儲於tempdb庫中,操作臨時表時,會引起跨庫操作。盡量用結果集和表變數來代替它。

17、盡量將數據的處理工作放在伺服器上,減少網路的開銷,如使用存儲過程。存儲過程是編譯好、優化過,並且被組織到一個執行規劃里、且存儲在資料庫中的 SQL語句,是控制流語言的集合,速度當然快。

18、不要在一段SQL或者存儲過程中多次使用相同的函數或相同的查詢語句,這樣比較浪費資源,建議將結果放在變數里再調用。這樣更快。

19、按照一定的次序來訪問你的表。如果你先鎖住表A,再鎖住表B,那麼在所有的存儲過程中都要按照這個順序來鎖定它們。如果你(不經意的)某個存儲過程中先鎖定表B,再鎖定表A,這可能就會導致一個死鎖。如果鎖定順序沒有被預先詳細的設計好,死鎖很難被發現

❻ 我裝的SQL,不知道怎麼開SQL空間

SQL
維基網路,自由的網路全書
SQL全稱是「結構化查詢語言(Structured Query Language)」,是資料庫中使用的標准數據查詢語言,IBM公司最早使用在其開發的資料庫系統中,1986年10月,美國ANSI對SQL進行規范後作為關系資料庫管理系統的標准語言(ANSI X3. 135-1986),1987年得到國際標准化組織的支持成為國際標准。不過各種通行的資料庫系統在實現過程中都對SQL規范作了某些擴充,所以實際上不同的資料庫系統的SQL語言不能完全相互通用。

SQL是高級的非過程化編程語言,允許用戶在高層數據結構上工作。他不要求用戶指定對數據的存放方法,也不需要用戶了解具體的數據存放方式,所以具有完全不同底層結構的不同資料庫系統可以使用相同的SQL語言作為數據輸入與管理的介面。它以記錄集合作為操縱對象,所有SQL語句接受集合作為輸入,返回集合作為輸出,這種集合特性允許一條SQL語句的輸出作為另一條SQL語句的輸入,所以SQL語言可以嵌套,這使他具有極大的靈活性和強大的功能,在多數情況下,在其他語言中需要一大段程序實現的一個單獨事件只需要一個SQL語句就可以達到目的,這也意味著用SQL語言可以寫出非常復雜的語句。

SQL同時也是資料庫文件格式的擴展名。

SQL語言包含4個部分:

數據查詢語言(SELECT語句)
數據操縱語言(INSERT, UPDATE, DELETE語句)
數據定義語言(如CREATE, DROP等語句)
數據控制語言(如COMMIT, ROLLBACK等語句)
取自"http://zh.wikipedia.org/wiki/SQL"

參考文獻:http://zh.wikipedia.org/wiki/SQL

❼ SQL中用T—SQL語句擴充資料庫文件為什麼說找不到.mdf的文件alter database users

正確的語法是這樣的:
ALTER DATABASE 庫名
MODIFY FILE
(NAME = 邏輯數據文件名,
SIZE = 40MB
)

use users
go
alter database users
modify file
(
name='users_data',--看你的users資料庫邏輯文件名是什麼
size=40MB --指定的大小要大於當前的大小
)
go

❽ SQL基本語句

掌握SQL四條最基本的數據*作語句 Insert Select Update和Delete 練掌握SQL是資料庫用戶的寶貴財 富 在本文中 我們將引導你掌握四條最基本的數據*作語句—SQL的核心功能—來依次介紹比較*作符 選擇斷言以及三值邏輯 當你完成這些學習後 顯然你已經開始算是精通SQL了 在我們開始之前 先使用CREATE TABLE語句來創建一個表 DDL語句對資料庫對象如表 列和視進行定義 它們並不對表中的行進行處理 這是因為DDL語句並不處理資料庫中實際的數據 這些工作由另一類SQL語句—數據*作語言(DML)語句進行處理 SQL中有四種基本的DML*作 INSERT SELECT UPDATE和DELETE 由於這是大多數SQL用戶經常用到的 我們有必要在此對它們進行一一說明 我們給出了一個名為EMPLOYEES的表 其中的每一行對應一個特定的雇員記錄 請熟悉這張表 我們在後面的例子中將要用到它 INSERT語句用戶可以用INSERT語句將一行記錄插入到指定的一個表中 例如 要將雇員John Smith的記錄插入到本例的表中 可以使用如下語句 INSERT INTO EMPLOYEES VALUES ( Smith John Los Angles );通過這樣的INSERT語句 系統將試著將這些值填入到相應的列中 這些列按照我們創建表時定義的順序排列 在本例中 第一個值 Smith 將填到第一個列LAST_NAME中 第二個值 John 將填到第二列FIRST_NAME中……以此類推 我們說過系統會 試著 將值填入 除了執行規則之外它還要進行類型檢查 如果類型不符(如將一個字元串填入到類型為數字的列中) 系統將拒絕這一次*作並返回一個錯誤信息 如果SQL拒絕了你所填入的一列值 語句中其他各列的值也不會填入 這是因為SQL提供對事務的支持 一次事務將資料庫從一種一致性轉移到另一種一致性 如果事務的某一部分失敗 則整個事務都會失敗 系統將會被恢復(或稱之為回退)到此事務之前的狀態 回到原來的INSERT的例子 請注意所有的整形十進制數都不需要用單引號引起來 而字元串和日期類型的值都要用單引號來區別 為了增加可讀性而在數字間插入逗號將會引起錯誤 記住 在SQL中逗號是元素的分隔符 同樣要注意輸入文字值時要使用單引號 雙引號用來封裝限界標識符 對於日期類型 我們必須使用SQL標准日期格式(yyyy mm dd) 但是在系統中可以進行定義 以接受其他的格式 當然 年臨近 請你最好還是使用四位來表示年份 既然你已經理解了INSERT語句是怎樣工作的了 讓我們轉到EMPLOYEES表中的其他部分 INSERT INTO EMPLOYEES VALUES ( Bunyan Paul Boston );INSERT INTO EMPLOYEES VALUES ( John Adams Boston );INSERT INTO EMPLOYEES VALUES ( Smith Pocahontas Los Angles );INSERT INTO EMPLOYEES VALUES ( Smith Bessie Boston );INSERT INTO EMPLOYEES VALUES ( Jones Davy Boston );INSERT INTO EMPLOYEES VALUES ( Jones Indiana Chicago NULL NULL);在最後一項中 我們不知道Jones先生的工薪級別和年薪 所以我們輸入NULL(不要引號) NULL是SQL中的一種特殊情況 我們以後將進行詳細的討論 現在我們只需認為NULL表示一種未知的值 有時 像我們剛才所討論的情況 我們可能希望對某一些而不是全部的列進行賦值 除了對要省略的列輸入NULL外 還可以採用另外一種INSERT語句 如下 INSERT INTO EMPLOYEES( FIRST_NAME LAST_NAME HIRE_DATE BRANCH_OFFICE)VALUE( Indiana Jones Indianapolis );這樣 我們先在表名之後列出一系列列名 未列出的列中將自動填入預設值 如果沒有設置預設值則填入NULL 請注意我們改變了列的順序 而值的順序要對應新的列的順序 如果該語句中省略了FIRST_NAME和LAST_NAME項(這兩項規定不能為空) SQL*作將失敗 讓我們來看一看上述INSERT語句的語法圖 INSERT INTO table [(column { column})]VALUES (columnvalue [{ columnvalue}]);和前一篇文?幸謊頤怯梅嚼ê爬幢硎究裳∠睿罄ê瘧硎究梢災馗慈我獯問南睿ú荒茉謔導實腟QL語句中使用這些特殊字元) VALUE子句和可選的列名列表中必須使用圓括弧 SELECT語句SELECT語句可以從一個或多個表中選取特定的行和列 因為查詢和檢索數據是資料庫管理中最重要的功能 所以SELECT語句在SQL中是工作量最大的部分 實際上 僅僅是訪問資料庫來分析數據並生成報表的人可以對其他SQL語句一竅不通 SELECT語句的結果通常是生成另外一個表 在執行過程中系統根據用戶的標准從資料庫中選出匹配的行和列 並將結果放到臨時的表中 在直接SQL(direct SQL)中 它將結果顯示在終端的顯示屏上 或者將結果送到列印機或文件中 也可以結合其他SQL語句來將結果放到一個已知名稱的表中 SELECT語句功能強大 雖然表面上看來它只用來完成本文第一部分中提到的關系代數運算 選擇 (或稱 限制 ) 但實際上它也可以完成其他兩種關系運算— 投影 和 連接 SELECT語句還可以完成聚合計算並對數據進行排序 SELECT語句最簡單的語法如下 SELECT columns FROM tables;當我們以這種形式執行一條SELECT語句時 系統返回由所選擇的列以及用戶選擇的表中所有指定的行組成的一個結果表 這就是實現關系投影運算的一個形式 讓我們看一下使用EMPLOYEES表的一些例子(這個表是我們以後所有SELECT語句實例都要使用的 而我們在圖 和圖 中給出了查詢的實際結果 我們將在其他的例子中使用這些結果) 假設你想查看雇員工作部門的列表 那下面就是你所需要編寫的SQL查詢 SELECT BRANCH_OFFICE FROM EMPLOYEES;由於我們在SELECT語句中只指定了一個列 所以我們的結果表中也只有一個列 注意結果表中具有重復的行 這是因為有多個雇員在同一部門工作(記住SQL從所選的所有行中將值返回) 要消除結果中的重復行 只要在SELECT語句中加上DISTINCT子句 SELECT DISTINCT BRANCH_OFFICEFROM EMPLOYEES;現在已經消除了重復的行 但結果並不是按照順序排列的 如果你希望以字母表順序將結果列出又該怎麼做呢?只要使用ORDER BY子句就可以按照升序或降序來排列結果 SELECT DISTINCT BRANCH_OFFICEFROM EMPLOYEESORDER BY BRANCH_OFFICE ASC;這一查詢的結果如表 所示 請注意在ORDER BY之後是如何放置列名BRANCH _OFFICE的 這就是我們想要對其進行排序的列 為什麼即使是結果表中只有一個列時我們也必須指出列名呢?這是因為我們還能夠按照表中其他列進行排序 即使它們並不顯示出來 列名BRANCH_ OFFICE之後的關鍵字ASC表示按照升序排列 如果你希望以降序排列 那麼可以用關鍵字DESC 同樣我們應該指出ORDER BY子句只將臨時表中的結果進行排序 並不影響原來的表 假設我們希望得到按部門排序並從工資最高的雇員到工資最低的雇員排列的列表 除了工資括弧中的內容 我們還希望看到按照聘用時間從最近聘用的雇員開始列出的列表 以下是你將要用到的語句 SELECT BRANCH_OFFICE FIRST_NAME LAST_NAME SALARY HIRE_DATEFROM EMPLOYEESORDER BY SALARY DESC HIRE_DATE DESC;這里我們進行了多列的選擇和排序 排序的優先順序由語句中的列名順序所決定 SQL將先對列出的第一個列進行排序 如果在第一個列中出現了重復的行時 這些行將被按照第二列進行排序 如果在第二列中又出現了重復的行時 這些行又將被按照第三列進行排序……如此類推 這次查詢的結果如表 所示 將一個很長的表中的所有列名寫出來是一件相當麻煩的事 所以SQL允許在選擇表中所有的列時使用*號 SELECT * FROM EMPLOYEES;這次查詢返回整個EMPLOYEES表 如表 所示 下面我們對開始時給出的SELECT語句的語法進行一下更新(豎直線表示一個可選項 允許在其中選擇一項 ) SELECT [DISTINCT] (column [{ columns}])| *FROM table [ { table}] <b lishixin/Article/program/Oracle/201311/18760

❾ 如何優化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列使用索引,而第一種查詢則不能使用索引。

❿ 誰能告訴我怎樣優化sql語句

(1)選擇最有效率的表名順序(只在基於規則的優化器中有效):Oracle的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最後的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。(2)WHERE子句中的連接順序:Oracle採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。(3)SELECT子句中避免使用『*』:Oracle在解析的過程中, 會將『*』依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間。(4)減少訪問資料庫的次數:Oracle在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變數 , 讀數據塊等。(5)在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次資料庫訪問的檢索數據量 ,建議值為200。(6)使用DECODE函數來減少處理時間:使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表。(7)整合簡單,無關聯的資料庫訪問:如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關系)。(8)刪除重復記錄:最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子:DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(9)用TRUNCATE替代DELETE:當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的信息. 如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(准確地說是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息。當命令運行後,數據不能被恢復.因此很少的資源被調用,執行時間也會很短。(TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)。(10)盡量多使用COMMIT:只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也會因為COMMIT所釋放的資源而減少,COMMIT所釋放的資源:a. 回滾段上用於恢復數據的信息。b. 被程序語句獲得的鎖。c. redo log buffer 中的空間。d. Oracle為管理上述3種資源中的內部花費。(11)用Where子句替換HAVING子句:避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後才對結果集進行過濾。這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷。(非oracle中)on、where、having這三個都可以加條件的子句中,on是最先執行,where次之,having最後,因為on是先把不符合條件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該速度是最快的,where也應該比having快點的,因為它過濾數據後才進行sum,在兩個表聯接時才用on的,所以在一個表的時候,就剩下where跟having比較了。在這單表查詢統計的情況下,如果要過濾的條件沒有涉及到要計算欄位,那它們的結果是一樣的,只是where可以使用rushmore技術,而having就不能,在速度上後者要慢如果要涉及到計算的欄位,就表示在沒計算之前,這個欄位的值是不確定的,根據上篇寫的工作流程,where的作用時間是在計算之前就完成的,而having就是在計算後才起作用的,所以在這種情況下,兩者的結果會不同。在多表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的聯接條件,把多個表合成一個臨時表後,再由where進行過濾,然後再計算,計算完後再由having進行過濾。由此可見,要想過濾條件起到正確的作用,首先要明白這個條件應該在什麼時候起作用,然後再決定放在那裡。(12)減少對表的查詢:在含有子查詢的SQL語句中,要特別注意減少對表的查詢。例子:SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
(13)通過內部函數提高SQL效率:復雜的SQL往往犧牲了執行效率。能夠掌握上面的運用函數解決問題的方法在實際工作中是非常有意義的。(14)使用表的別名(Alias):當在SQL語句中連接多個表時, 請使用表的別名並把別名前綴於每個Column上。這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤。(15)用EXISTS替代IN、用NOT EXISTS替代NOT IN:在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率。在子查詢中,NOT IN子句將執行一個內部的排序和合並。無論在哪種情況下,NOT IN都是最低效的 (因為它對子查詢中的表執行了一個全表遍歷)。為了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS。例子:(高效)SELECT * FROM EMP (基礎表)
WHERE EMPNO > 0 AND EXISTS (SELECT 『X' FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 『MELB')
(低效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0
AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = 『MELB')
(16)識別『低效執行』的SQL語句:雖然目前各種關於SQL優化的圖形化工具層出不窮,但是寫出自己的SQL工具來解決問題始終是一個最好的方法:SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
(17)用索引提高效率:索引是表的一個概念部分,用來提高檢索數據的效率,Oracle使用了一個復雜的自平衡B-tree結構。通常,通過索引查詢數據比全表掃描要快。當Oracle找出執行查詢和Update語句的最佳路徑時, Oracle優化器將使用索引。同樣在聯結多個表時使用索引也可以提高效率。另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證。那些LONG或LONG RAW數據類型, 你可以索引幾乎所有的列。通常, 在大型表中使用索引特別有效. 當然,你也會發現, 在掃描小表時,使用索引同樣能提高效率。雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價。索引需要空間來存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改。這意味著每條記錄的INSERT, DELETE , UPDATE將為此多付出4, 5次的磁碟I/O 。因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢。定期的重構索引是有必要的:ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
(18)用EXISTS替換DISTINCT:當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT。一般可以考慮用EXIST替換, EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足後,立刻返回結果。例子:(低效):
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO
(高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 『X'
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
(19)SQL語句用大寫的;因為Oracle總是先解析SQL語句,把小寫的字母轉換成大寫的再執行。(20)在Java代碼中盡量少用連接符「+」連接字元串。(21)避免在索引列上使用NOT通常,我們要避免在索引列上使用NOT, NOT會產生在和在索引列上使用函數相同的影響。當Oracle「遇到」NOT,他就會停止使用索引轉而執行全表掃描。(22)避免在索引列上使用計算。WHERE子句中,如果索引列是函數的一部分。優化器將不使用索引而使用全表掃描。舉例:低效:
SELECT … FROM DEPT WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
(23)用>=替代>:高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
兩者的區別在於, 前者DBMS將直接跳到第一個DEPT等於4的記錄而後者將首先定位到DEPTNO=3的記錄並且向前掃描到第一個DEPT大於3的記錄。(24)用UNION替換OR (適用於索引列):通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果。對索引列使用OR將造成全表掃描。注意, 以上規則只針對多個索引列有效. 如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低。在下面的例子中, LOC_ID 和REGION上都建有索引。高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = 「MELBOURNE」
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = 「MELBOURNE」
(25)用IN來替換OR:這是一條簡單易記的規則,但是實際的執行效果還須檢驗,在Oracle8i下,兩者的執行路徑似乎是相同的:低效:SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30高效:SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);(26)避免在索引列上使用IS NULL和IS NOT NULL:避免在索引中使用任何可以為空的列,Oracle將無法使用該索引。對於單列索引,如果列包含空值,索引中將不存在此記錄。對於復合索引,如果每個列都為空,索引中同樣不存在此記錄.如果至少有一個列不為空,則記錄存在於索引中。舉例: 如果唯一性索引建立在表的A列和B列上, 並且表中存在一條記錄的A,B值為(123,null) , Oracle將不接受下一條具有相同A,B值(123,null)的記錄(插入)。 然而如果所有的索引列都為空,Oracle將認為整個鍵值為空而空不等於空。因此你可以插入1000 條具有相同鍵值的記錄,當然它們都是空! 因為空值不存在於索引列中,所以WHERE子句中對索引列進行空值比較將使ORACLE停用該索引。低效: (索引失效)SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;高效: (索引有效)SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;(27)總是使用索引的第一個列:如果索引是建立在多個列上, 只有在它的第一個列(leading column)被where子句引用時,優化器才會選擇使用該索引。這也是一條簡單而重要的規則,當僅引用索引的第二個列時,優化器使用了全表掃描而忽略了索引。(28)用UNION-ALL 替換UNION ( 如果有可能的話):當SQL語句需要UNION兩個查詢結果集合時,這兩個結果集合會以UNION-ALL的方式被合並, 然後在輸出最終結果前進行排序。如果用UNION ALL替代UNION, 這樣排序就不是必要了。效率就會因此得到提高。需要注意的是,UNION ALL 將重復輸出兩個結果集合中相同記錄。因此各位還是要從業務需求分析使用UNION ALL的可行性. UNION 將對結果集合排序,這個操作會使用到SORT_AREA_SIZE這塊內存。對於這塊內存的優化也是相當重要的。下面的SQL可以用來查詢排序的消耗量:
低效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
(29)用WHERE替代ORDER BY:ORDER BY 子句只在兩種嚴格的條件下使用索引。ORDER BY中所有的列必須包含在相同的索引中並保持在索引中的排列順序。ORDER BY中所有的列必須定義為非空。WHERE子句使用的索引和ORDER BY子句中所使用的索引不能並列。例如: 表DEPT包含以下列:DEPT_CODE PK NOT NULLDEPT_DESC NOT NULLDEPT_TYPE NULL低效: (索引不被使用)SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE高效: (使用索引)SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0(30)避免改變索引列的類型:當比較不同數據類型的數據時, ORACLE自動對列進行簡單的類型轉換。 假設 EMPNO是一個數值類型的索引列:SELECT … FROM EMP WHERE EMPNO = 『123'。 實際上,經過Oracle類型轉換, 語句轉化為: SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(『123') 。幸運的是,類型轉換沒有發生在索引列上,索引的用途沒有被改變。現在,假設EMP_TYPE是一個字元類型的索引列:SELECT … FROM EMP WHERE EMP_TYPE = 123 。這個語句被Oracle轉換為: SELECT … FROM EMP WHERETO_NUMBER(EMP_TYPE)=123。因為內部發生的類型轉換, 這個索引將不會被用到! 為了避免Oracle對你的SQL進行隱式的類型轉換, 最好把類型轉換用顯式表現出來。注意當字元和數值比較時, Oracle會優先轉換數值類型到字元類型。(31)需要當心的WHERE子句:某些SELECT 語句中的WHERE子句不使用索引。這里有一些例子:(1)『!=' 將不使用索引。記住, 索引只能告訴你什麼存在於表中, 而不能告訴你什麼不存在於表中。(2)『||'是字元連接函數。就象其他函數那樣, 停用了索引。(3)『+'是數學函數。就象其他數學函數那樣, 停用了索引。(4)相同的索引列不能互相比較,這將會啟用全表掃描。(32)a. 如果檢索數據量超過30%的表中記錄數.使用索引將沒有顯著的效率提高。b. 在特定情況下, 使用索引也許會比全表掃描慢, 但這是同一個數量級上的區別。而通常情況下,使用索引比全表掃描要塊幾倍乃至幾千倍!(33)避免使用耗費資源的操作:帶有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL語句會啟動SQL引擎執行耗費資源的排序(SORT)功能。DISTINCT需要一次排序操作, 而其他的至少需要執行兩次排序. 通常, 帶有UNION, MINUS , INTERSECT的SQL語句都可以用其他方式重寫. 如果你的資料庫的SORT_AREA_SIZE調配得好, 使用UNION , MINUS, INTERSECT也是可以考慮的, 畢竟它們的可讀性很強。(34)優化GROUP BY:提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉。下面兩個查詢返回相同結果但第二個明顯就快了許多。
低效:
SELECT JOB, AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = 'PRESIDENT'
OR JOB = 'MANAGER'高效:
SELECT JOB, AVG(SAL)
FROM EMP
WHERE JOB = 'PRESIDENT'
OR JOB = 'MANAGER'
GROUP JOB