sql 優化過程之union 替換 or
在網上看了一些sql優化的文章,其中有一條就是使用union 替換 or。原因是在索引列上使用or,會使索引失效,從而走全表掃描。說的比較籠統,我今天特意試驗了一下:在什麼情況下可以用union 替換 or才會使索引生效。
create table t as select * from all_objects;
然後又在t上新增了一列id,使用object_id填充的。
create index ind_t_id on t(id);只在id上建立索引。
set autotrace traceonly
select * from t where object_id=10 or id=20;
SQL> select * from t where object_id=10 or id=20;
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 1539 | 229 (1)| 00:00:03 |
|* 1 | TABLE ACCESS FULL| T | 9 | 1539 | 229 (1)| 00:00:03 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"=10 OR "ID"=20)
Note
-----
- dynamic sampling used for this statement
統計資訊
----------------------------------------------------------
0 recursive calls
0 db block gets
815 consistent gets
0 physical reads
0 redo size
1176 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
這種情況下索引失效。
select * from t where object_id=10
union
select * from id=20;
SQL> select * from t where object_id=10
2 union
3 select * from t where id=20;
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 298853808
--------------------------------------------------------------------------------
----------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |
--------------------------------------------------------------------------------
----------
| 0 | SELECT STATEMENT | | 10 | 1710 | 231 (2)|
00:00:03 |
| 1 | SORT UNIQUE | | 10 | 1710 | 231 (2)|
00:00:03 |
| 2 | UNION-ALL | | | | |
|
|* 3 | TABLE ACCESS FULL | T | 9 | 1539 | 228 (1)|
00:00:03 |
| 4 | TABLE ACCESS BY INDEX ROWID| T | 1 | 171 | 1 (0)|
00:00:01 |
|* 5 | INDEX RANGE SCAN | IND_T_ID | 1 | | 1 (0)|
00:00:01 |
--------------------------------------------------------------------------------
----------
Predicate Information (identified by operation id):
---------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("OBJECT_ID"=10)
5 - access("ID"=20)
Note
-----
- dynamic sampling used for this statement
統計資訊
----------------------------------------------------------
13 recursive calls
0 db block gets
958 consistent gets
0 physical reads
0 redo size
1176 bytes sent via SQL*Net to client
405 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed
可以發現union替換or之後,索引生效。
然後我在object_id上建立索引,再看看情況是什麼樣的:
create index ind_t on t(object_id);
select * from t where object_id=10 or id=20;
SQL> select * from t where object_id=10 or id=20;
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 3010370457
--------------------------------------------------------------------------------
-------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU
)| Time |
--------------------------------------------------------------------------------
-------------
| 0 | SELECT STATEMENT | | 9 | 1539 | 148 (0
)| 00:00:02 |
| 1 | TABLE ACCESS BY INDEX ROWID | T | 9 | 1539 | 148 (0
)| 00:00:02 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | |
| |
| 3 | BITMAP OR | | | |
| |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | |
| |
|* 5 | INDEX RANGE SCAN | IND_T | | | 1 (0
)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | |
| |
|* 7 | INDEX RANGE SCAN | IND_T_ID | | | 1 (0
)| 00:00:01 |
--------------------------------------------------------------------------------
-------------
可以發現這種情況下,即使使用了or,索引還是有效地。
當然這種情況使用union也是索引有效地。
結論:
有索引和無索引的一列 進行or連線時。使用union替換or會使索引生效。而兩列都有索引時。or和union都是可以使用索引的。
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22418990/viewspace-1054729/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【SQL優化】UNION替換OR效率測試及總結SQL優化
- 【SQL最佳化】UNION替換OR效率測試及總結SQL
- SQL優化案例-union代替or(九)SQL優化
- Oracle SQL語句優化之UNIONOracleSQL優化
- union 優化方法優化
- SQL Server 替換SQLServer
- UNION效率比UNION ALL效率高——SQL優化之Everything is possibleSQL優化
- 【轉】UNION效率比UNION ALL效率高——SQL優化之Everything is possibleSQL優化
- SQL Union和SQL Union All用法(轉)SQL
- Oracle優化案例-union代替or(九)Oracle優化
- MySQL union的一種優化MySql優化
- sql中union和union allSQL
- SQL最佳化案例-union代替or(九)SQL
- 效能優化 (八) APK 加固之動態替換 Application優化APKAPP
- 循序漸進調優union相關的sqlSQL
- 在sql語句中替換Not In 的方法SQL
- Oracle優化案例-又見union代替or(二十)Oracle優化
- Oracle union all 不走索引的優化Oracle索引優化
- sql中union和union all的用法SQL
- 【SQL】UNION ALL 與UNION 的區別SQL
- SQL UNION 和 UNION ALL 操作符SQL
- 通過新增條件優化SQL優化SQL
- 一條sql的優化過程SQL優化
- php文章內容替換為內鏈,有助於SEO優化PHP優化
- 長列表優化之滾動替換資料方案小記優化
- 通過SQL PROFILE自動優化SQL語句SQL優化
- Aspose.Words使用教程之在文件中找到並替換文字
- SQL中的替換函式replace()使用SQL函式
- sql中UNION和UNION ALL的區別SQL
- 通過hint push_subq優化sql優化SQL
- SQL Server資料庫內容替換方法SQLServer資料庫
- sql 正則替換資料庫語句!SQL資料庫
- 【SQL優化】SQL優化工具SQL優化
- sql注入之union注入SQL
- HTML 替換元素與非替換元素HTML
- SQL Server優化之SQL語句優化SQLServer優化
- 一條SQL語句的優化過程SQL優化
- 優化同事發過來的一個sql優化SQL