第一篇:高效SQL語句
1.SELECT子句中避免使用 “*”
當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用 ?*? 是一個方便的方法.不幸的是,這是一個非常低效的方法.實際上,ORACLE在解析的過程中, 會將“*” 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間.2.使用DECODE函數來減少處理時間
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.例如:
Sql代碼
1.SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0020 ANDENAME LIKE ?SMITH%?;
2.SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE ?SMITH%?;
SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0020 ANDENAME LIKE ?SMITH%?;
SELECT COUNT(*),SUM(SAL)FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE ?SMITH%?;
你可以用DECODE函數高效地得到相同結果:
Sql代碼
1.SELECT COUNT(DECODE(DEPT_NO,0020,?X?,NULL))D0020_COUNT,2.COUNT(DECODE(DEPT_NO,0030,?X?,NULL))D0030_COUNT,3.SUM(DECODE(DEPT_NO,0020,SAL,NULL))D0020_SAL,4.SUM(DECODE(DEPT_NO,0030,SAL,NULL))D0030_SAL5.FROM EMP WHERE ENAME LIKE ?SMITH%?;
SELECT COUNT(DECODE(DEPT_NO,0020,?X?,NULL))D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,?X?,NULL))D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL))D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL))D0030_SAL FROM EMP WHERE ENAME LIKE ?SMITH%?;
類似的,DECODE函數也可以運用于GROUP BY 和ORDER BY子句中.3.刪除重復記錄
最高效的刪除重復記錄方法(因為使用了ROWID)
Sql代碼
1.DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
DELETE FROM EMP E WHERE E.ROWID >(SELECT MIN(X.ROWID)FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
4.用TRUNCATE替代DELETE
當刪除表中的記錄時,在通常情況下,回滾段(rollback segments)用來存放可以被恢復的信息,如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況),而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息.當命令運行后,數據不能被恢復.因此很少的資源被調用,執行時間也會很短.5.計算記錄條數
和一般的觀點相反, count(*)比count(1)稍快,當然如果可以通過索引檢索,對索引列的計數仍舊是最快的.例如 COUNT(EMPNO)
6.用Where子句替換HAVING子句
避免使用HAVING子句,HAVING 只會在檢索出所有記錄之后才對結果集進行過濾,這個處理需要排序、總計等操作,如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷, 例如:
Sql代碼
1.--低效
2.SELECT REGION,AVG(LOG_SIZE)FROM LOCATION GROUP BY REGION HAVING REGION REGION!= ?SYDNEY? AND REGION!= ?PERTH?3.--高效
4.SELECT REGION,AVG(LOG_SIZE)FROMLOCATION WHERE REGION REGION!= ?SYDNEY? ND REGION!= ?PERTH? GROUP BY REGION
--低效
SELECT REGION,AVG(LOG_SIZE)FROM LOCATION GROUP BY REGION HAVING REGION REGION!= ?SYDNEY? AND REGION!= ?PERTH?--高效
SELECT REGION,AVG(LOG_SIZE)FROMLOCATION WHERE REGION REGION!= ?SYDNEY? ND REGION!= ?PERTH? GROUP BY REGION
7.用EXISTS替代IN
在許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率.Sql代碼1.--低效
2.SELECT * FROM EMP WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ?MELB?)
3.--高效:
4.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?)
--高效:
SELECT * FROM EMP WHERE EMPNO > 0 AND EXISTS(SELECT ?X?FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ?MELB?)
8.用NOT EXISTS替代NOT IN
在子查詢中,NOT IN子句將執行一個內部的排序和合并.無論在哪種情況下,NOT IN都是最低效的(因為它對子查詢中的表執行了一個全表遍歷).為了避免使用NOT IN,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.例如:
SELECT …FROM EMPWHERE DEPT_NO NOT IN(SELECT DEPT_NO FROM DEPT WHERE DEPT_CAT=?A?);
Sql代碼
1.--為了提高效率改寫為:(方法一: 高效)
SELECT ….FROM EMP A,DEPT B WHERE A.DEPT_NO = B.DEPT(+)AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+)= ?A?2.--(方法二: 最高效)
SELECT ….FROM EMP E WHERE NOT EXISTS(SELECT ?X?FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = ?A?);3.--為了提高效率改寫為:(方法一: 高效)
SELECT ….FROM EMP A,DEPT B WHERE A.DEPT_NO = B.DEPT(+)AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+)= ?A?
4.--(方法二: 最高效)
SELECT ….FROM EMP E WHERE NOT EXISTS(SELECT ?X?FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = ?A?);
9.用EXISTS替換DISTINCT
當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT.一般可以考慮用EXIST替換 例如:
Sql代碼1.--低效:
2.SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO3.--高效:
4.SELECT DEPT_NO,DEPT_NAMEFROM DEPT D WHERE EXISTS(SELECT ?X? FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
5.--EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果.--低效:
SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO
--高效:
SELECT DEPT_NO,DEPT_NAMEFROM DEPT D WHERE EXISTS(SELECT ?X? FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
--EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果.10.用索引提高效率
索引是表的一個概念部分,用來提高檢索數據的效率,實際上ORACLE使用了一個復雜的自平衡B-tree結構,通常通過索引查詢數據比全表掃描要快,當ORACLE找出執行查詢和Update語句的最佳路徑時,ORACLE優化器將使用索引,同樣在聯結多個表時使用索引也可以提高效率,另一個使用索引的好處是,它提供了主鍵(primary key)的唯一性驗證,除了那些LONG或LONG RAW數據類型, 你可以索引幾乎所有的列.通常, 在大型表中使用索引特別有效.當然,你也會發現, 在掃描小表時,使用索引同樣能提高效率,雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價.索引需要空間來存儲,也需要定期維護,每當有記錄在表中增減或索引列被修改時,索引本身也會被修改,這意味著每條記錄的INSERT , DELETE , UPDATE將為此多付出4 , 5 次的磁盤I/O,因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢注:定期的重構索引是有必要的.11.避免在索引列上使用計算
WHERE子句中,如果索引列是函數的一部分,優化器將不使用索引而使用全表掃描.舉例:Sql代碼
1.--低效:
2.SELECT …FROM DEPT WHERE SAL * 12 > 25000;3.--高效:
4.SELECT … FROM DEPT WHERE SAL> 25000/12;--低效:
SELECT …FROM DEPT WHERE SAL * 12 > 25000;--高效:
SELECT … FROM DEPT WHERE SAL> 25000/12;
12.用>=替代>
Sql代碼
1.--如果DEPTNO上有一個索引2.--高效:
SELECT *FROM EMPWHERE DEPTNO >=4
3.--低效:
SELECT *FROM EMPWHERE DEPTNO >3--如果DEPTNO上有一個索引 4.--高效:
SELECT *FROM EMPWHERE DEPTNO >=45.--低效:
SELECT *FROM EMPWHERE DEPTNO >3
兩者的區別在于, 前者DBMS將直接跳到第一個DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個DEPT大于3的記錄.
第二篇:高效的SQL語句
如何寫高效率的SQL語句、Where子句中的連接順序:
ORACLE采用自下而上的順序解析WHERE子句。
根據這個原理,表之間的連接必須寫在其他WHERE條件之前,那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。
舉例:
(低效)
select...from table1 t1 where t1.sal > 300 and t1.jobtype = '0001' and 20 <(select count(*)from table1 t2 where t2.pno = t1.tno;
(高效)
select...from table1 t1 where 20 <(select count(*)from table1 t2 where t2.pno = t1.tno and t1.sal > 300 and t1.jobtype = '0001';
2、Select子句中避免使用 “ * ”:
當你想在select子句中列出所有的column時,使用動態SQL列引用 ‘*' 是一個方便的方法。不幸的是,這是一個非常低效的方法。
實際上,ORACLE在解析的過程中,會將 '*' 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間。
3、減少訪問數據庫的次數:
當執行每條SQL語句時,ORACLE在內部執行了許多工作:
解析SQL語句、估算索引的利用率、綁定變量、讀數據塊等等。
由此可見,減少訪問數據庫的次數,就能實際上減少ORACLE的工作量。
舉例:
題目——我要查找編號為0001、0002學生的信息。
(低效)
select name,age,gender,address from t_student where id = '0001';
select name,age,gender,address from t_student where id = '0002';
(高效)
select a.name,a.age,a.gender,a.address,b.name,b.age,b.gender,b.address from t_student a,t_student b where a.id = '0001' and b.id = '0002';
4、使用Decode函數來減少處理時間:
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表。
舉例:
(低效)
select count(*), sum(banace)from table1 where dept_id = '0001' and name like 'anger%';select count(*), sum(banace)from table1 where dept_id = '0002' and name like 'anger%';(高效)
select count(decode(dept_id,'0001','XYZ',null))count_01,count(decode(dept_id,'0002','XYZ',null))
count_02,sum(decode(dept_id,'0001',dept_id,null))sum_01,sum(decode(dept_id,'0002',dept_id,null))sum_02
from table1
where name like 'anger%';
5、整合簡單,無關聯的數據庫訪問:
如果你有幾個簡單的數據庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關系)
舉例:
(低效)
select name from table1 where id = '0001';
select name from table2 where id = '0001';
select name from table3 where id = '0001';
(高效)
select t1.name, t2.name, t3.name
from table1 t1, table2 t2, table3 t3
where t1.id(+)= '0001' and t2.id(+)= '0001' and t3.id(+)= '0001'
【注:上面例子雖然高效,但是可讀性差,需要量情而定啊!】
6、刪除重復記錄:
最高效的刪除重復記錄方法(因為使用了ROWID)
舉例:
delete from table1 t1
where t1.rowid >(select min(t2.rowid)from table1 t2 where t1.id = t2.id);
7、盡量不要使用having子句,可以考慮用where替換。
having只會在檢索出所有記錄之后才對結果集進行過濾.這個處理需要排序,總計等操作。如果能通過where子句限制記錄的數目,那就能減少這方面的開銷。
8、盡量用表的別名:
當在SQL語句中連接多個表時,請使用表的別名并把別名前綴于每個Column上。這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤。
9、用exists替代in(發現好多程序員不知道這個怎么用):
在許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。在這種情況下,使用exists(或not exists)通常將提高查詢的效率。
舉例:
(低效)
select...from table1 t1 where t1.id > 10 and pno in(select no from table2 where name like 'www%');
(高效)
select...from table1 t1 where t1.id > 10 and exists(select 1 from table2 t2 where t1.pno = t2.no and name like 'www%');
10、用not exists替代not in:
在子查詢中,not in子句將執行一個內部的排序和合并。
無論在哪種情況下,not in都是最低效的(因為它對子查詢中的表執行了一個全表遍歷)。為了避免使用not in,我們可以把它改寫成外連接(Outer Joins)或not exists。
11、用exists替換distinct:
當提交一個包含一對多表信息的查詢時,避免在select子句中使用distinct.一般可以考慮用exists替換
舉例:
(低效)
select distinct d.dept_no, d.dept_name from t_dept d, t_emp e where d.dept_no = e.dept_no;(高效)
select d.dept_no, d.dept_name from t_dept d where exists(select 1 from t_emp where d.dept_no = e.dept_no);
exists使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果.12、用表連接替換exists:
通常來說,采用表連接的方式比exists更有效率。
舉例:
(低效)
select ename from emp e where exists(select 1 from dept where dept_no = e.dept_no and dept_cat = 'W');
SELECT ENAME
(高效)
select ename from dept d, emp e where e.dept_no = d.dept_no and dept_cat = 'W';
13、避免在索引列上使用is null和is not null
避免在索引中使用任何可以為空的列,ORACLE將無法使用該索引。
對于單列索引,如果列包含空值,索引中將不存在此記錄;
對于復合索引,如果每個列都為空,索引中同樣不存在此記錄;
如果至少有一個列不為空,則記錄存在于索引中。
舉例:
如果唯一性索引建立在表的A列和B列上, 并且表中存在一條記錄的A,B值為(123,null),ORACLE將不接受下一條具有相同A,B值(123,null)的記錄(插入),然而如果所有的索引列都為空,ORACLE將認為整個鍵值為空而空不等于空。
因此你可以插入1000 條具有相同鍵值的記錄,當然它們都是空!
因為空值不存在于索引列中,所以WHERE子句中對索引列進行空值比較將使ORACLE停用該索引。
14、最好把復雜的sql,去看下它的執行計劃,這樣有利于你分析知道自己的sql效率如何。
第三篇:sql常用語句
//創建臨時表空間
create temporary tablespace test_temp
tempfile 'E:oracleproduct10.2.0oradatatestservertest_temp01.dbf'size 32m
autoextend on
next 32m maxsize 2048m
extent management local;
//創建數據表空間
create tablespace test_data
logging
datafile 'E:oracleproduct10.2.0oradatatestservertest_data01.dbf'size 32m
autoextend on
next 32m maxsize 2048m
extent management local;
//創建用戶并指定表空間
create user username identified by password
default tablespace test_data
temporary tablespace test_temp;
//給用戶授予權限
//一般用戶
grant connect,resource to username;
//系統權限
grant connect,dba,resource to username
//創建用戶
create user user01 identified by u01
//建表
create table test7272(id number(10),name varchar2(20),age number(4),joindate date default sysdate,primary key(id));
//存儲過程
//數據庫連接池
數據庫連接池負責分配、管理和釋放數據庫連接
//
//創建表空間
create tablespace thirdspace
datafile 'C:/Program Files/Oracle/thirdspace.dbf' size 10mautoextend on;
//創建用戶
create user binbin
identified by binbin
default tablespace firstspace
temporary tablespace temp;
//賦予權限
GRANT CONNECT, SYSDBA, RESOURCE to binbin
//null與""的區別
簡單點說null表示還沒new出對象,就是還沒開辟空間
個對象裝的是空字符串。
//建視圖
create view viewname
as
sql
//建索引
create index indexname on tablename(columnname)
//在表中增加一列
alter table tablename add columnname columntype
//刪除一列
alter table tablename drop columnname
//刪除表格內容,表格結構不變
truncate table tableneme
//新增數據
insert into tablename()values()
//直接新增多條數據
insert into tablename()
selecte a,b,c
from tableabc
//更新數據 new除了對象,但是這“”表示
update tablename set columnname=? where
//刪除數據
delete from tablename
where
//union語句
sql
union
sql
//case
case
when then
else
end
第四篇:SQL語句
SQL練習
一、設有如下的關系模式,試用SQL語句完成以下操作:
學生(學號,姓名,性別,年齡,所在系)
課程(課程號,課程名,學分,學期,學時)
選課(學號,課程號,成績)
1. 求選修了課程號為“C2”課的學生學號
2. 求選修了課程號為“C2”課的學生學號和姓名
3. 求沒有選修課程號為“C2”課的學生學號
4. 求選修了課程號為“C2”,又選修了課程號為“C3”課的學生學號
5.求選修了課程號為“C2”或“C3”課的學生學號
6.求選修了全部課程的學生學號
7.求至少選修了學號為“98002”的學生所學過的所有課程的學生的學號和姓名。
8.查詢學生選課表中的全部數據
9.查詢計算機系學生的姓名、年齡
10.查詢成績在70—80分之間的學生的學號、課程號和成績
11.查詢計算機系年齡在18—20之間且性別為“男”的學生的姓名和年齡
12.查詢成績在80分以上的學生的姓名、課程號和成績,并按成績的降序排列結果。
13.查詢哪些課程沒有人選修,要求列出課程號和課程名。
14.查詢數學系成績在80分以上的學生的學號,姓名
15.查詢課程號為“C02”的課程的最高分數。
16.查詢計算機系學生的最大年齡和最小年齡。
17.統計每個系的學生人數。
18.統計每門課程的選課人數和考試最高分。
19.統計每個學生的選課門數和考試總成績,并按選課門數的升序顯示結果。
20.查詢總成績超過200分的學生,要求列出學號、總成績。
21.用子查詢實現如下查詢:
(1)查詢選修了課程號“C01”的學生的姓名和所在系。
(2)查詢數學系成績在80分以上的學生的學號和姓名。
(3)查詢計算機系考試成績最高的學生的姓名。
22.刪除選課成績小于60分的學生的選課記錄。
23.將所有選修了課程“C01”的學生的成績加10分。
24.將計算機系所有選修了課程“計算機文化基礎”課程的學生的成績加10分。
25.創建查詢學生的學號、姓名、所在系、課程號、課程名、課程學分的視圖。
26.創建查詢每個學生的平均成績的視圖,要求列出學生學號和平均成績。
27.創建查詢每個學生的選課學分的視圖,要求列出學生學號及總學分。
第五篇:SQL語句
SQL語句,用友的SQL2000,通過查詢管理器寫的語句
1、查詢
2、修改
3、刪除
4、插入
表名:users 包含字段:id,sname,sage
查詢 select * from users查詢users表中所有數據
select id,sname,sage from users查詢users表中id,sname,sage字段所有數據
可以限定查詢條件比如:
select sname from users where sage>20查詢年齡大于20歲的所有人的名字
修改 update users set sname='李四',sage=22將users表中數據都改為姓名李四,年齡22
update users set sname='李四',sage=22 where id=1限定id為1的人的信息修改為
姓名李四,年齡22
可以加where條件。
刪除 delete from users where id=2刪除users表中id為2的一行數據delete from users 代表刪除users中所有數據
插入 insert into users(id,sname,sage)values(5,'劉三',21)插入一條數據
SQL四條最基本的數據操作語句:Insert,Select,Update和Delete。
例如:SELECT columns FROM tables;其中columns為列的名稱,tables為表格名稱
1、查詢:select 字段名 from 表名 where 條件
查找在表(如A)中符合條件的字段
2、修改:update 表名 set 字段名=‘所要修改的內容’
修改在表(如A)中的字段的值為:所要修改的內容
3、刪除: delete from 表名 where 條件
刪除符合條件的表(如A)中的信息
4、插入: insert into 表名(字段名)(‘插入內容’)
在表(如A)中插入字段為:插入內容 的一條信息