計算查詢條件是or區間時候的selectivity和Cardinality
-------------------建立測試表
create table t1(
v1,
n1,
n2
)
as
select
to_char(mod(rownum,20)),
rownum,
mod(rownum,20)
from
all_objects
where
rownum <= 3000
;
------------------收集統計資訊
begin
dbms_stats.gather_table_stats(ownname => 'scott',
tabname => 't1',
no_invalidate => FALSE,
estimate_percent => 100,
method_opt => 'for all columns size 1',
cascade => true);
end;
/
----------------查詢,觀察Cardinality的值
SQL> select count(*) from t1 where n2>2 or n2<=2;
COUNT(*)
----------
3000
執行計劃
----------------------------------------------------------
Plan hash value: 3724264953
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 6 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | TABLE ACCESS FULL| T1 | 2733 | 8199 | 6 (0)| 00:00:01 |
---------------------------------------------------------------------------
Cardinality是2733,看看怎麼算出來的。
首先我們肯定知道ORALCE估算的是不對的,正確的應該是3000才對。
看看ORACLE的演算法。
The selectivity of (predicate1 OR predicate2)
= selectivity of (predicate1) + selectivity of (predicate2) - selectivity of (predicate1 AND predicate2)
其中:
selectivity of (predicate1) =(high_value – limit) / (high_value – low_value)=(19-2)/(19-0)=0.894736842
selectivity of (predicate2) = (high_value – limit) / (high_value – low_value) + 1/num_distinct=(2-0)/(19-0)+1/20=0.155263158
注意第二個謂詞由於是個閉區間,因此需要增加1/num_distinct部分,而第一部分是個開區間,就不需要了
因此
The selectivity of (predicate1 OR predicate2)
=(0.894736842+0.155263158)-(0.894736842*0.155263158)
=0.911080332
Cardinality=num_rows*selectivity=2733
SQL> select 3000*0.911080332 from dual;
3000*0.911080332
----------------
2733.241
跟oracle計算出來的是吻合的
如果採用是繫結變數,每個謂詞的選擇率固定為5%。
The selectivity of (predicate1 OR predicate2)
= selectivity of (predicate1) + selectivity of (predicate2) - selectivity of (predicate1 AND predicate2)
=5%+5%-5%*5%=9.75%
驗證下:
SQL> explain plan for
2 select count(*) from t1 where n2>:1 or n2<=:2;
已解釋。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3724264953
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 7 (15)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 3 | | |
|* 2 | TABLE ACCESS FULL| T1 | 293 | 879 | 7 (15)| 00:00:01 |
---------------------------------------------------------------------------
Cardinality=num_rows*selectivity=3000*0.0975=292.5~293
吻合
SQL> select 3000*0.0975 from dual;
3000*0.0975
-----------
292.5
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-695423/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JN專案-時間查詢條件驗證
- PostgreSQL多值列的選擇性-Statistics,Cardinality,Selectivity,EstimateSQL
- mysql條件查詢MySql
- MongoDB查詢條件MongoDB
- mysql查詢中時間、日期加減計算MySql
- 查詢條件和條數,先查詢兩條免費的,後面為vip
- Laravel MongoDB 時間區間查詢的問題LaravelMongoDB
- Laravel 多條件查詢Laravel
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- Mybatis-技術專區-Criteria的and和or進行聯合條件查詢MyBatis
- SpringBoot Jpa多條件查詢Spring Boot
- AntDesignBlazor示例——列表查詢條件Blazor
- golang beego orm 查詢條件 or andGolangORM
- Javaweb-DQL-條件查詢JavaWeb
- 查詢條件封裝物件封裝物件
- mongodb條件查詢不等於MongoDB
- 【mybatis-plus】條件查詢MyBatis
- Laravel 多條件查詢時粗心導致的一個 BUGLaravel
- 20240719資料庫關聯查詢、條件查詢資料庫
- 34. 過濾條件、多表查詢、子查詢
- SQL-基礎語法 - 條件查詢 - 邏輯運算SQL
- Linq查詢之多個排序條件排序
- Linq兩個from查詢條件
- 菜品條件分頁查詢
- hyperf關聯模型條件查詢模型
- mysql拆分字串做條件查詢MySql字串
- jQuery 條件搜尋查詢 實時取值 升降序排序jQuery排序
- mysql like查詢 - 根據多個條件的模糊匹配查詢MySql
- SQL-基礎語法 - 條件查詢 - 模糊查詢SQL
- 日期區間查詢
- 關於sqlserver字元型別查詢條件區分大小寫SQLServer字元型別
- Mybatis實現條件IN查詢(foreach)和invalid comparison異常MyBatis
- mysql多條件過濾查詢之mysq高階查詢MySql
- MybatisPlus入門(五)MybatisPlus條件查詢MyBatis
- Vue請求介面查詢條件拼接Vue
- mybatis-plus QueryWrapper條件查詢器MyBatisAPP
- 報表查詢條件的 N 種使用方式
- MySQL全面瓦解7:查詢的過濾條件MySql
- mysql帶AND關鍵字的多條件查詢MySql