日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一个filter子查询测试

發布時間:2024/8/23 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个filter子查询测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分析日志的時候發現,一個sql執行非常慢。看執行計劃是因為not in子查詢走了filter執行計劃。類似于下面測試的情形。 測試數據:
drop table test1;
create table test1 as select object_id,object_name from dba_objects where rownum<=1000;
create table test2 as select object_id,object_name from dba_objects where rownum<=1000;
analyze table test1 compute statistics for table for all indexes for all indexed columns;
analyze table test2 compute statistics for table for all indexes for all indexed columns; 表結構:
SQL> desc test1
Name Type Nullable Default Comments
----------- ------------- -------- ------- --------
OBJECT_ID NUMBER Y
OBJECT_NAME VARCHAR2(128) Y SQL> desc test2
Name Type Nullable Default Comments
----------- ------------- -------- ------- --------
OBJECT_ID NUMBER Y
OBJECT_NAME VARCHAR2(128) Y
執行計劃:
1、原始sql類似下面的查詢
從下面執行計劃來看,子查詢TEST2走了filter執行計劃。而我們知道filter執行計劃,test1返回多少條記錄,test2要掃描多少次。當test1和test2數據量都比較大的時候,效率可想而知。
SQL> select *
2 from test1
3 where object_id not in (select object_id from test2); 未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 3110810548 ----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 968 | 21296 | 66 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| TEST1 | 1000 | 22000 | 3 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| TEST2 | 2 | 26 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter( NOT EXISTS (SELECT 0 FROM "TEST2" "TEST2" WHERE
LNNVL("OBJECT_ID"<>:B1)))
3 - filter(LNNVL("OBJECT_ID"<>:B1))
統計信息
----------------------------------------------------------
0 recursive calls
0 db block gets
4091 consistent gets
0 physical reads
0 redo size
204 bytes sent via SQL*Net to client
236 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
通過
alter table test1 modify (object_id not null);

alter table test2 modify (object_id not null);
都走上面的filter執行計劃。 2、將test1和test2的object_id都modify為not null。
下面這個執行計劃為hash-anti連接。test1和test2都通過一次掃描即可搞定。
SQL> select *
2 from test1
3 where test1.object_id is not null
4 and test1.object_id not in
5 (select object_id from test2 where object_id is not null); 未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 2299773985 ------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 35 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN RIGHT ANTI| | 1 | 35 | 7 (15)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | TEST2 | 1000 | 13000 | 3 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | TEST1 | 1000 | 22000 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------ Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("TEST1"."OBJECT_ID"="OBJECT_ID")
2 - filter("OBJECT_ID" IS NOT NULL)
3 - filter("TEST1"."OBJECT_ID" IS NOT NULL) Note
-----
- dynamic sampling used for this statement
統計信息
----------------------------------------------------------
8 recursive calls
0 db block gets
26 consistent gets
0 physical reads
0 redo size
204 bytes sent via SQL*Net to client
236 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed 由上面這兩個測試,主要想說明一個問題:
當執行not in操作時,如果主查詢和子查詢關聯字段,表定義都可以為null,即使表里相應字段不為null。
Oracle在解析并生成執行計劃階段,它只能通過現有統計信息去生成執行計劃,而這個階段還沒有查具體的數據,所以它并不清楚字段是不是有空值,而定義該字段可以為空,那么就按可以為空算嘍。 11g中,會直接走hash-anti半連接。這個算是在11g之前的一個書寫規則問題吧。 ?

轉載于:https://www.cnblogs.com/zhaoshuangshuang/archive/2012/09/03/2669325.html

總結

以上是生活随笔為你收集整理的一个filter子查询测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。