SQL優化常用方法36

2021-09-22 19:06:13 字數 3078 閱讀 2566

用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"

如果你堅持要用or, 那就需要返回記錄最少的索引列寫在最前面.

注意: where key1 = 10 (返回最少記錄) or key2 = 20 (返回最多記錄)

oracle 內部將以上轉換為

where key1 = 10 and

((not key1 = 10) and key2 = 20)

譯者按: 下面的測試資料僅供參考: (a = 1003 返回一條記錄 , b = 1 返回1003條記錄)

sql> select from unionvsor /1st test*/

2 where a = 1003 or b = 1;

1003 rows selected.

0 select statement optimizer=choose

1 0 concatenation

2 1 table access (by index rowid) of 'unionvsor'

3 2 index (range scan) of 'ub' (non-unique)

4 1 table access (by index rowid) of 'unionvsor'

5 4 index (range scan) of 'ua' (non-unique)

0 recursive calls

0 db block gets

144 consistent gets

0 physical reads

0 redo size

63749 bytes sent via sql*net to client

7751 bytes received via sql*net from client

68 sql*net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1003 rows processed

sql> select from unionvsor /2nd test*/

2 where b = 1 or a = 1003 ;

1003 rows selected.

0 select statement optimizer=choose

1 0 concatenation

2 1 table access (by index rowid) of 'unionvsor'

3 2 index (range scan) of 'ua' (non-unique)

4 1 table access (by index rowid) of 'unionvsor'

5 4 index (range scan) of 'ub' (non-unique)

0 recursive calls

0 db block gets

143 consistent gets

0 physical reads

0 redo size

63749 bytes sent via sql*net to client

7751 bytes received via sql*net from client

68 sql*net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1003 rows processed

sql> select from unionvsor /3rd test*/

2 where a = 1003

3 union

4 select * from unionvsor

5 where b = 1;

1003 rows selected.

0 select statement optimizer=choose

1 0 sort (unique)

2 1 union-all

3 2 table access (by index rowid) of 'unionvsor'

4 3 index (range scan) of 'ua' (non-unique)

5 2 table access (by index rowid) of 'unionvsor'

6 5 index (range scan) of 'ub' (non-unique)

0 recursive calls

0 db block gets

10 consistent gets

0 physical reads

0 redo size

63735 bytes sent via sql*net to client

7751 bytes received via sql*net from client

68 sql*net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

1003 rows processed

用union的效果可以從consistent gets和 sql*net的資料交換量的減少看出

SQL優化常用方法38

避免在索引列上使用is null和is not null 避免在索引中使用任何可以為空的列,oracle將無法使用該索引 對於單列索引,如果列包含空值,索引中將不存在此記錄.對於復合索引,如果每個列都為空,索引中同樣不存在此記錄.如果至少有乙個列不為空,則記錄存在於索引中 舉例 如果唯一性索引建立在...

SQL優化常用方法18

用exists替代in 在許多基於基礎表的查詢中,為了滿足乙個條件,往往需要對另乙個表進行聯接.在這種情況下,使用exists 或not exists 通常將提高查詢的效率.低效 select from emp 基礎表 where empno 0 and deptno in select deptn...

SQL優化常用方法5

where子句中的連線順序 oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where條件之前,那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾.例如 低效,執行時間156.3秒 select from emp e where sal 50000 ...