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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

查询计划中集的势(Cardinality)的计算

發布時間:2024/8/26 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 查询计划中集的势(Cardinality)的计算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

當使用CBO模式的優化器時,oracle在生成查詢計劃時,會計算各個訪問路徑的代價,選擇代價最小的訪問路徑作為查詢計劃。這個選擇過程我們可以通過做一個10053的trace來觀察。

在做代價估算時,有一個很重要的參數作為代價計算的因數,這就掃描字段的集的勢(cardinality)。那么這個值是如何計算的呢?這個值的計算根據索引情況及查詢條件不同而不同,因而它的計算也比較復雜。下面我們只討論在使用綁定變量的情況下集的勢的計算。

集的勢總的計算公式是:

集的勢?= MAX(集的勢因子?*?記錄數, 1)

?

可以看出,影響集的勢的值的主要因素是集的勢因子。在不同情況下,這個因子的計算公式不同,下面我們就討論不同情況下的集的勢因子的計算。

索引字段

對于建立了索引(可以是復合索引)的字段,如果查詢條件是“=”,字段的集的勢計算公式如下:

集的勢因子?= 1 /?字段上的唯一值數

?

讓我們做個測試看,

SQL> create table T_PEEKING3 (a NUMBER, b char(1), c char(5)); ? Table created. ? SQL> SQL> create index T_PEEKING3_IDX1 on T_PEEKING3(b, c); ? Index created. ? SQL> SQL> begin ? 2??? for i in 1..1000 loop ? 3????? insert into T_PEEKING3 values (i, mod(i, 10), mod(i, 13)); ? 4??? end loop; ? 5??? commit; ? 6? end; ? 7? / ? PL/SQL procedure successfully completed. ? SQL> SQL> analyze table T_PEEKING3 compute statistics for table for all indexes for all indexed columns; ? Table analyzed.

?

表的記錄數為1000,字段(B, C)上建立了索引,它們的唯一值數分別為:

SQL> select count(distinct b) from T_PEEKING3; ? COUNT(DISTINCTB) ---------------- ????????????? 10 ? SQL> SQL> select count(distinct c) from T_PEEKING3; ? COUNT(DISTINCTC) ---------------- ????????????? 13 ? SQL> SQL> select count(*) from ? 2? ( ? 3? select distinct b, c from T_PEEKING3 ? 4? ); ? ? COUNT(*) ---------- ?????? 130

?

因此,B字段的集的勢為round(1/10 * 1000) = 100,

select /*+index(a T_PEEKING3_IDX1)*/ * from T_PEEKING3 a where b=:V; ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=55? Cardinality=100?? Bytes=1500 TABLE ACCESS BY INDEX ROWID?????? Object name=T_PEEKING3??? Cost=55? Cardinality=100? Bytes=1500 ? INDEX RANGE SCAN??????? Object name=T_PEEKING3_IDX1??????? Cost=1?? Cardinality=100?

?

因此,C字段的集的勢為round(1/13 * 1000) = 77,

select /*+index(a T_PEEKING3_IDX1)*/ * from T_PEEKING3 a where c=:V; ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=21? Cardinality=77??? Bytes=1386 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=21? Cardinality=77??? Bytes=1386 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=77???

?

?

?

如果索引字段查詢條件是“<”“>”“<=”“>=”,則計算公式為,

集的勢因子?= (1 /?字段上的唯一值數) + (1/記錄數)

?

例:當查詢條件為c > :1,它的集的勢為round((1/13 + 1/1000)*1000) = 78

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where c > :1 ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=22? Cardinality=78??? Bytes=1404 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=22? Cardinality=78??? Bytes=1404 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=78??? ????????

?

?

如果索引字段查詢條件是in,則計算公式為,

集的勢因子?= in條件中的變量數?/?字段上的唯一值數

?

例:當查詢條件為c in (:1, :2, :3),它的集的勢為round(3/13 * 1000) = 231

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? c in (:1, :2, :3); ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=57? Cardinality=231?? Bytes=4158 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=57? Cardinality=231?? Bytes=4158 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=231??

?

?

如果索引字段查詢條件是“<>”,則計算公式為,

集的勢因子?= (1 – (1/字段上的唯一值數))

這時的集的勢值也是這個字段上可以達到的最大集的勢值。

?

例:當查詢條件為c <> :1,它的集的勢為round((1 – 1/13) * 1000) = 923

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? c <> :1 ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=219 Cardinality=923?? Bytes=16614 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=219 Cardinality=923?? Bytes=16614 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=923??

?

?

當查詢條件為not in時,計算就更為復雜了。它是根據not in中的變量值按階計算的。

集的勢因子?= (1 – (1/字段上的唯一值數))^(not in中變量數)

?

例:當查詢條件為c not in (:1, :2, :3),它的集的勢為round((1 – 1/13)^3 * 1000) = 787

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? c not in (:1, :2, :3) ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=187 Cardinality=787?? Bytes=14166 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=187 Cardinality=787?? Bytes=14166 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=787??

非索引字段

當查詢條件為?“=”、“in” 時,非索引字段的集的勢因子是,

集的勢因子?= 1/100

?

例:以下集的勢為?1/100 * 1000 = 10

select * from T_PEEKING3 where a = :1; SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=2?? Cardinality=10??? Bytes=180 TABLE ACCESS FULL Object name=T_PEEKING3?? Cost=2?? Cardinality=10??? Bytes=180

?

當查詢條件為“<”、“>”、“<=”、“>=”、“<>”、“not in” 時,非索引字段的集的勢因子是,

集的勢因子?= 1/20

?

例:以下集的勢為?1/100 * 1000 = 10

select * from T_PEEKING3 where a < :1; SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=2?? Cardinality=10??? Bytes=180 TABLE ACCESS FULL Object name=T_PEEKING3?? Cost=2?? Cardinality=50??? Bytes=180

?

多字段

對于多個字段同時在查詢條件中,集的勢因子計算公式如下,

集的勢因子?=?字段1的集的勢因子?*?字段2的集的勢因子?* … *字段n的集的勢因子

?

例:以下兩個字段的復合集的勢為round(((1/10 + 1/1000)*(1/13)) * 1000) = 8,

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? b > :1 and c = :2; SELECT STATEMENT, GOAL = CHOOSE??? ???????? Cost=4?? Cardinality=8???? Bytes=144 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=4?? Cardinality=8???? Bytes=144 ? INDEX RANGE SCAN ?????? Object name=T_PEEKING3_IDX1??????? Cost=1?? Cardinality=8??? ????????

?

例:以下查詢的集的勢為round(((3/10) * 1/13) * 1000) = 23

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? b in (:1, :2, :3) and c = :2; ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=7?? Cardinality=23??? Bytes=414 INLIST ITERATOR??????????????????????????????????? ? TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=7?? Cardinality=23??? Bytes=414 ?? INDEX RANGE SCAN Object name=T_PEEKING3_IDX1???? Cost=1?? Cardinality=23???

?

例:以下查詢的集的勢為round((2/10) * (1/13 + 1/1000) * 1000) = 16

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? b in (:1, :2) and c > :2; ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=5?? Cardinality=16??? Bytes=288 INLIST ITERATOR??????????????????????????????????? ? TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=5?? Cardinality=16??? Bytes=288 ?? INDEX RANGE SCAN Object name=T_PEEKING3_IDX1???? Cost=1?? Cardinality=16??? ????????

?

例:以下查詢的集的勢為round((2/10) * (3/13) * 1000) = 46

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? b in (:1, :2) and c in (:1, :2, :3); ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=12? Cardinality=46??? Bytes=828 INLIST ITERATOR??????????????????????????????????? ? TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=12? Cardinality=46??? Bytes=828 ?? INDEX RANGE SCAN Object name=T_PEEKING3_IDX1???? Cost=1?? Cardinality=46???

?

例:以下查詢的集的勢為round((1-1/10) * ((1- 1/13)^2) * 1000) = 767

select /*+index(a T_PEEKING3_IDX1)*/* from T_PEEKING3 a where? b <>:1? and c not in (:2, :3) ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=183 Cardinality=767?? Bytes=13806 TABLE ACCESS BY INDEX ROWID Object name=T_PEEKING3 Cost=183 Cardinality=767?? Bytes=13806 ? INDEX FULL SCAN Object name=T_PEEKING3_IDX1?????? Cost=3?? Cardinality=767??

?

例:以下查詢的集的勢為round((1/20) * (1/13 + 1/1000) * 1000) = 4

select * from T_PEEKING3 where a not in (:1) and c > :2; ? SELECT STATEMENT, GOAL = CHOOSE Cost=68???? Cardinality=4??? Bytes=732 TABLE ACCESS FULL Object name=T_PEEKING3?? Cost=2?? Cardinality=4???? Bytes=732???????

?

全表掃描

對于全表掃描,如果沒有查詢條件時,

集的勢因子?= 1

?

例:以下集的勢為?1 * 1000 = 1000

select * from T_PEEKING3; ? SELECT STATEMENT, GOAL = CHOOSE???????????????????? Cost=2?? Cardinality=1000? Bytes=18000 TABLE ACCESS FULL Object name=T_PEEKING3?? Cost=2?? Cardinality=1000? Bytes=18000

?

?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的查询计划中集的势(Cardinality)的计算的全部內容,希望文章能夠幫你解決所遇到的問題。

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