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
創建的索引。
Select * from employee
where
first_name ='Beill' and last_name ='Cliton'
遇到下面這種情況又如何處理呢?如果一個變量(name)中存放著 Bill
Cliton 這個員工的姓名, 對於這種情況我們又如何避免全程遍歷, 使用索引呢?
可以使用一個函數, 將變量 name 中的姓和名分開就可以了, 但是有一點需 要注
意,這個函數是不能作用在索引列上。下面是 SQL 查詢腳本:
select * from employee
where
first_name = SUBSTR('&&name',1,INSTR('&&name',' ')-1)
and
last_name = SUBSTR('&&name',INSTR('&&name’,' ')+1)
3. 帶通配符(%)的 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'
再看下面這個例子:
select * from employee where salary<>3000;
對這個查詢,可以改寫為不使用 NOT:
select * from employee where salary<3000 or salary>3000;
雖然這兩種查詢的結果一樣, 但是第二種查詢方案會比第一種查詢方案更快
些。 第二種查詢允許 Oracle 對 salary 列使用索引, 而第一種查詢則不能使用索
引。
6. IN 和 EXISTS
有時候會將一列和一系列值相比較。 最簡單的辦法就是在 where 子句中使用
子查詢。在 where 子句中可以使用兩種格式的子查詢。
第一種格式是使用 IN 操作符:
... where column in(select * from ... where ...);
第二種格式是使用 EXIST 操作符:
... where exists (select 'X' from ...where ...);
我相信絕大多數人會使用第一種格式, 因為它比較容易編寫, 而實際上第二
種格式要遠比第一種格式的效率高。 在 Oracle 中可以幾乎將所有的 IN 操作符子
查詢改寫為使用 EXISTS 的子查詢。
第二種格式中,子查詢以‘select 'X'開始。運用 EXISTS 子句不管子查詢
從表中抽取什麼數據它只查看 where 子句。 這樣優化器就不必遍歷整個表而僅根
據索引就可完成工作(這裡假定 在 where 語句中使用的列存在索引)。相對於
IN 子句來說,EXISTS 使用相連子查詢,構造起來要比 IN 子查詢困難一些。
通過使 用 EXIST,Oracle 系統會首先檢查主查詢,然後運行子查詢直到它
找到第一個匹配項,這就節省了時間。Oracle 系統在執行 IN 子查詢時,首先執
行子查詢, 並將獲得的結果列表存放在在一個加了索引的臨時表中。 在執行子查
詢之前, 系統先將主查詢掛起, 待子查詢執行完畢, 存放在臨時表中以後再執行
主查 詢。這也就是使用 EXISTS 比使用 IN 通常查詢速度快的原因。
同時應盡可能使用 NOT EXISTS 來代替 NOT IN,盡管二者都使用了 NOT(不
能使用索引而降低速度),NOT EXISTS 要比 NOT IN 查詢效率更高
搞明白什麼是高效就可以了。
主要是減少事務的運行是 查詢時遍歷的數據量,查詢的次數。
再看看網上有專門寫得好的專門實現某功能的SQL語句。
首先說說怎麼用SQL語句創建數據庫,創建數據庫的語句有如下幾種:
1. CREATE TABLE(創建新表)
2. CREATE INDEX(增加索引)
3. DROP INDEX(刪除索引)
4. CONSTRAINT(約束語句)
5. ALTER TABLE(修改表)
6. DROP TABLE(刪除表)
CREATE TABLE語句:
在數據庫中生成新表,表中字段的類型能夠為:INTEGER(整型)、LONG(長整型)、 SINGLE(單精度浮點數)、DOUBLE(雙精度浮點數)、DATETIME(日期型,也能夠寫成DATE)、BIT(布爾型)、 TEXT(字符串型,最大255個字節)、MEMO(字符串型,最大可達1.2G字節)、 COUNTER(自動遞增長整型,可確定記錄的唯一性)、CURRENCY(貨幣型,精確到小數點左邊15位,右邊4位)、 BINARY(字節型,最大255個)、LONGBINARY(用於OLE對象)、GUID(全局唯一標識符)。
生成表NewTable,該表有文本字段Field1和整型字段Field2,表名和字段名能夠隨便您取,不區分大小寫,但是,有些保留字不能用作表名字段名,比如Number
CREATE TABLE NewTable(Field1 TEXT(30), Field2 INTEGER);
CREATE INDEX語句:
INDEX是為了加快查找記錄的速度,或是為了增加字段約束關系而配置的。
創建索引語句執行前表中能夠有記錄,但存在的記錄必須滿足該索引語句的約束關系,否則語句不能執行,另外要注意的是在同一個數據庫中(而不但僅是在同一個表中),索引名不能相同,否則語句也會失敗。
生成字段Field1的索引字段NewIndex,兩條語句作用相同
生成後Field1字段能夠有相同的值,能夠有空值(NULL)
CREATE INDEX NewIndex ON NewTable (Field1);
CREATE INDEX NewIndex ON NewTable (Field1) WITH IGNORE NULL;
生成字段Field1的索引字段NewIndex,注意,每個表裡只能有一個主索引(PRIMARY)。生成後Field1字段不能有相同的值,不能有空值(當然,假如是TEXT類型,能夠有一個空串,但是空串不是空值)
CREATE INDEX NewIndex ON NewTable(Field1) WITH PRIMARY;
字段Field1不能有相同的值,但能夠有空值(兩個空值不算相同的值)
CREATE UNIQUE INDEX NewIndex ON NewTable(Field1);
字段Field1能夠有相同的值,但不能有空值
CREATE INDEX NewIndex ON NewTable(Field2) WITH DISALLOW NULL
能夠在索引語句中加入ASC(升序)或DESC(降序)來控制記錄排列順序假如不使用順序字,SQL則默認使用ASC順序
CREATE INDEX NewIndex ON NewTable(Field1 ASC, Field2 DESC);
DROP INDEX語句:
刪除表NewTable中的索引NewIndex,語句執行前索引NewIndex必須存在
DROP INDEX NewIndex ON NewTable;
CONSTRAINT語句:
CONSTRAINT子句用於創建數據庫完整性的索引,他和INDEX語句作用相同,有些地方能夠互相替代......余下全文>>