程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 理解 DB2 中列組統計信息

理解 DB2 中列組統計信息

編輯:DB2教程

簡介

DB2 SQL 優化器(後文簡稱為優化器)可以估計每個備選訪問計劃的執行成本,並根據其估計結果選擇一個最佳訪問計劃。一個訪問計劃可以指定用來解析一條 SQL 語句的操作次序。

為正確地確定每種訪問計劃的成本,DB2 優化器需要准確的基數估計值。基數估計是這樣一種過程:在應用了謂詞或執行了聚集之後,優化器使用統計信息確定部分查詢結果的大小。對於訪問計劃的每個操作符,優化器將估計該操作符的基數輸出。一個或更多謂詞的應用可以減少輸出流基數。

在計算謂詞對於基數估計值的組合過濾效果時,通常會假設這些謂詞彼此之間是獨立的。然而,這些謂詞可以在統計方面彼此關聯。單獨地處理它們通常會導致優化器低估基數值。而基數值的低估又會導致優化器選擇一個次優的訪問計劃。

對於至少應用了至少兩個本地等式謂詞的 SQL 語句,優化器將考慮使用多列統計信息來檢測統計關聯,並更加准確地估計多個謂詞組合的過濾效果。同樣對於連接兩個或更多表的 SQL 語句,以及在一對表間至少使用了兩個等式連接謂詞的連接,優化器也會使用多列統計信息。

一個本地等式謂詞是一個應用於單個表的等式謂詞,其描述如下所示:

理解 DB2 中列組統計信息 COLUMN = literal

其中 literal 可以是以下任一內容:

一個常量值;

一個參數標記或一個主變量;

一個專用寄存器(例如,CURRENT DATE)

一個等式連接謂詞的描述如下所示,它用於表 1 和表 2 間的連接:

理解 DB2 中列組統計信息 T1.COLUMN = T2.COLUMN

DB2 V8.2 使用下面的多列統計信息:

索引 keycard 統計信息:FIRST2KEYCARD、FIRST3KEYCARD、FIRST4KEYCARD 和 FULLKEYCARD

列組統計信息:列組基數值

這些統計信息描述了包含兩個或更多列的列集中不同分組的數量。

在 DB2 V8.2 出現之前,只能使用索引 keycard 統計信息,並且要受下列條件約束:

索引必須是完全限定的。如果鍵中的所有列都可以被等式謂詞 引用(連接謂詞或本地謂詞,但不是兩者的混合),那麼這個索引就是完全限定的。

對於連接謂詞,索引也必須是惟一的。

在 DB2 V8.2 中,通過考慮到所有索引 keycard 統計信息而不要求索引完全限定,DB2 SQL 優化器進一步擴展了多列統計信息的使用。它還考慮到了用戶收集的任何列組統計信息。本文討論了優化器如何利用這些統計信息,以及用戶如何識別要收集的列組統計信息。

多個本地等式謂詞的統計相關性

DB2 SQL 優化器試圖檢測多個本地等式謂詞間的統計相關性。

示例 1:假設有一個表 SHOW_LISTINGS,它包含如下列:


表 1. SHOW_LISTINGS 表的描述

列名 描述 SHOW_ID 表外鍵,包含關於各演出清單的信息 CHANNEL_ID 表外鍵,包含關於播放演出的每個頻道的信息 STATION_ID 表外鍵,包含和頻道相關的每個電視台的信息 CITY_ID 表外鍵,包含關於上演該演出的每個城市的信息 DAY 演出播放的日期 TIME 演出播放的當天的時間 <other columns> 描述了演出清單的其他屬性

由於演出只在某個電視台的某個頻道播出,在一天的特定時間內,這些列(SHOW_ID,CHANNEL_ID,STATION_ID 和 TIME)彼此之間不是互相獨立的。DAY 列獨立於 TIME 列,但是它不獨立於所有演出清單的 SHOW_ID。

設想一條應用了以下謂詞的 SQL 語句:

P1: SHOW_ID = ?
P2: CHANNEL_ID = ?
P3: STATION_ID = ?
P4: TIME = ?

如果存在這樣一個索引,其中的鍵包含謂詞 P1-P4 引用的所有列,或者鍵中的前四列包含所引用的列,優化器將使用 FIRST4KEYCARD 索引統計信息(如果收集了索引統計信息的話),來檢測謂詞 P1-P4 之間的統計相關性。在應用了這四個謂詞之後,優化器將計算一個更准確的基數估計值。例如,下面的任何一個索引可以用來檢測這四個謂詞間的統計相關性:

IX1 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME)
IX2 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME, CITY_ID)
IX3 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME, DAY, CITY_ID)

優化器使用 IX1 的 FULLKEYCARD 和 FIRST4KEYCARD 統計信息來檢測所有四個謂詞的相關性。類似地,它也可以使用 IX2 和 IX3 的 FIRST4KEYCARD。

不能使用如下所示的索引:

IX4 ON SHOW_LISTINGS(CITY_ID, SHOW_ID, CHANNEL_ID, STATION_ID, TIME)

由於每個 keycard 統計信息都將包含 CITY_ID 列,因此該列上未定義本地等式謂詞。

如果不存在具有所需鍵的索引,那麼可以在 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 上收集列組統計信息。優化器使用這些列組統計信息,運用與處理索引的 FIRST4KEYCARD 統計信息相同的方式檢測這四個謂詞間的統計相關性。

DB2 優化器同樣也會考慮具有謂詞子集的索引或者列組統計信息。例如,看下面所示的索引:

IX5 ON SHOW_LISTINGS(SHOW_ID, STATION_ID, CITY_ID, CHANNEL_ID)

該索引不能使用 FIRST2KEYCARD 來檢測謂詞 P1 和 P3 的統計相關性。盡管只是部分糾正了謂詞 P1-P4 間的統計相關性,但已足以允許優化器選擇一個優秀的查詢執行計劃。此外,盡管索引 IX5 中的完整鍵包含 CHANNEL_ID 列,仍然不能使用 FULLKEYCARD 統計信息來檢測與 P2 的相關性,因為它包含的 CITY_ID 列沒有在謂詞中引用。

多個等式連接謂詞的統計相關性

DB2 SQL 優化器同樣嘗試檢測兩個表中的多個等式連接謂詞間的統計相關性。

示例 2:考慮示例 1 中描述的 SHOW_LISTINGS 表,另外,RATINGS 表包含如下列:


表 2. RATINGS 表的描述

列名 描述 SHOW_ID 表外鍵,包含關於各演出清單的信息 CHANNEL_ID 表外鍵,包含關於播放演出的每個頻道的信息 STATION_ID 表外鍵,包含和頻道相關的每個電視台的信息 CITY_ID 表外鍵,包含關於上演該演出的每個城市的信息 DAY 播放演出的日期 TIME 播放演出的時間 RATING 在一天的某個時間,在特定城市中,某個電視台頻道的演出清單的收視率

RATINGS 表包含描述不同城市演出清單的收視率信息,用戶可能需要查詢 RATINGS 表和 SHOW_LISTINGS 表的連接以檢索這兩個表的屬性。一個查詢在該連接上應用的謂詞集包含以下內容:

P1: SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID
P2: SHOW_LISTINGS.CHANNEL_ID = RATINGS.CHANNEL_ID
P3: SHOW_LISTINGS.STATION_ID = RATINGS.STATION_ID

P1-P3 這三個謂詞可能不是互相獨立的;優化器試圖使用任何可用的多列統計信息來檢測謂詞之間的相關性。

優化器只能檢測和說明每一對連接表上的多個連接謂詞間的統計相關性。例如,如果一條 SQL 語句包含如下謂詞:

P1: T1.A = T2.A
P2: T1.B = T2.B
P3: T1.C = T3.C

優化器只嘗試檢測 P1 和 P2 間的統計相關性,因為它們只應用於相同的兩個表的連接,T1 和 T2。P3 應用於 T1 和 T2 的連接;那是一個不同的連接。如果添加了第四個謂詞,例如:

P4: T1.D = T2.D

優化器將進一步嘗試檢測 P3 和 P4 間的統計相關性。

為了說明等式連接謂詞間的統計相關性,優化器使用連接所涉及的兩表之一的多列統計信息;這個表被視為連接的父表。因此只需要在連接的父表中收集列組統計信息。連接的另一個表被指定為子表。如果父表不能確定,那麼優化器就不能使用多列統計信息來檢測連接謂詞間的統計相關性。

附錄 B 提供了優化器如何確定兩個連接表中的父表和子表的具體示例和描述。對連接中的父表進行標識,或者判斷連接中是否有父表,這對於避免收集無用的列組統計信息是非常有用的。如果尚無合適的索引可用,那麼在連接中的每個表上收集列組統計信息即可。

收集多列統計信息

優化器考慮使用所有可用的索引 keycard 統計信息。如果具有統計相關性的謂詞所引用的列集中,索引 keycard 統計信息不可用,可以使用 RUNSTATS 命令收集列組統計信息。下面是從 DB2 V82 提取的語法。

注意:對於 DB2 9,請在 Info Center 的 DB2 9 文檔中查看語法。.

      >>-RUNSTATS--ON TABLE--table name--+-USE PROFILE------------+--->
                  '-| Statistics Options |-'
      Statistics Options:
                       .-ALLOW WRITE Access-.
      |--+--------------------------+--+--------------------+--------->
        '-| Table Object Options |-' '-ALLOW READ Access--'
      Table Object Options:
      |--+-FOR--| Index Clause |----------------------------------+---|
          '-+-------------------------+--+-----------------------+-'
            '-| Column Stats Clause |-' '-AND--| Index Clause |-'
      Column Stats Clause:
      |--+-ON--| Cols Clause |------------------------------+---------|
          '-+---------------------+--| Distribution Clause |-'
            '-ON--| Cols Clause |-'
      On Cols Clause:
          .-ON ALL COLUMNS-------------------------------------------------.
          |                      .-,-------------.  |
          |                      V        |  |
        |--+-ON--+----------------------+--COLUMNS--(----Column Option-+--)-+--|
          |   '-+-ALL-+--COLUMNS AND-'                   |
          |    '-KEY-'                         |
          '-ON KEY COLUMNS-------------------------------------------------'
      

“ON COLUMNS” 子句允許您指定一個列的列表,為它們收集統計信息。如果您指定了一組列,則會收集該組中惟一值的數量。未列出的列的統計信息非常明確。您可以在 “on-cols-clause” 和 “on-dist-cols-clause” 中使用這個子句。

注意:目前還不支持為一組列收集分布統計信息。

注意:如果啟用了 automatic runstats 並使用 RUNSTATS 命令收集了列組統計信息,automatic runstats 將覆蓋這些統計信息,並丟棄列組統計信息。

AUTO_RUNSTATS 數據庫配置設置表明是否啟用了 automatic runstats:

Automatic runstats (AUTO_RUNSTATS)=ON

如果設置為 “ON”,則啟用 automatic runstats。

AUTO_RUNSTATS 默認情況下使用 “具有所有分布和示例的詳細索引” 的 RUNSTATS 選項。

您可以使用統計信息配置文件來覆蓋默認的 RUNSTATS 選項。您可以將希望收集的任意列組統計信息添加到此配置文件中,以避免 automatic runstats 覆蓋它們。

“統計信息配置文件” 提供了關於統計信息配置文件的詳細資料。

對於數據庫分區特性(database partitioning feature,DPF)環境,automatic runstats 總是在目錄分區上收集統計信息。如果表不存在於這個目錄節點上,將使用表駐留的節點組的第一個分區。

將使用 RUNSTATS 命令的 “ON COLUMNS” 選項收集列組統計信息。例如,使用 SHOW_LISTINGS 表收集 SHOW_LISTINGS.SHOW_ID、SHOW_LISTINGS.CHANNEL_ID 和 SHOW_LISTINGS.STATION_ID 中的列組統計信息,執行如下 RUNSTATS 命令:

        RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID,
  STATION_ID))
      

如果只在 DAY 列收集列統計信息以及收集 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 列的列組統計信息,則執行以下的 RUNSTATS 命令:

        RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID,
  STATION_ID, TIME), DAY)
      

注意:列統計信息是在列組中列出的所有列上收集的。在上面的命令中,列統計信息同樣是在每一個列中收集的(SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME)。

為了收集所有列的統計信息以及在 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 中收集列組統計信息,執行下面的 RUNSTATS 命令:

        RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON ALL COLUMNS AND ON COLUMNS
  ((SHOW_ID, CHANNEL_ID, STATION_ID, TIME))
      

要收集多個多列統計信息,可以提供一個組集。下面的 RUNSTATS 命令在組(SHOW_ID、CHANNEL_ID 和 STATION_ID)和組(SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME)中收集多列統計信息,同樣也在 DAY 列上收集了列統計信息:

        RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID,
  CHANNEL_ID, STATION_ID), (SHOW_ID, CHANNEL_ID, STATION_ID, TIME), DAY)
      

注意:對於索引統計信息來說,將為索引鍵的前兩個列、前三列和前四列收集多個多列統計信息,而一個列組基數統計信息是為指定的各列組收集的。

確定何時收集列組統計信息

確定何時收集列組統計信息以及要收集哪些列組統計信息是比較困難的。這一節將為您介紹一些方法,幫助您確定何時需要列組統計信息。

本節的示例使用了 SAMPLE 數據庫,可以通過執行 “db2sampl” 創建,此數據庫使用 db2level:

Informational tokens are "DB2 v8.1.1.120", "s060801", "U808888", and FixPak "13".

示例 3:本地等式謂詞

創建了 SAMPLE 數據庫後,並沒有在表上收集統計信息。首先,需要在 EMPLOYEE 表中收集統計信息:

RUNSTATS ON TABLE SCHEMA_NAME.EMPLOYEE WITH DISTRIBUTION;

考慮 SAMPLE 數據庫中 EMPLOYEE 表上的如下查詢:

SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
FROM EMPLOYEE
WHERE JOB='ANALYST';

該查詢從 EMPLOYEE 表返回兩條記錄:

EMPNO FIRSTNME   LASTNAME    WORKDEPT SEX JOB   SALARY  
------ ------------ --------------- -------- --- -------- -----------
000130 DOLORES   QUINTANA    C01   F  ANALYST   23800.00
000140 HEATHER   NICHOLLS    C01   F  ANALYST   28420.00
2 record(s) selected.

看一下為此查詢選擇的查詢執行計劃。

為此,使用 EXPLAIN 工具,它要求 EXPLAIN 表存在。

為了創建 EXPLAIN 表,執行以下代碼: db2 -tvf $DB2PATH/misc/EXPLAIN.DDL

創建了 EXPLAIN 表之後,像下面這樣對查詢進行 EXPLAIN 處理: SET CURRENT EXPLAIN MODE EXPLAIN;
SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
FROM EMPLOYEE
WHERE JOB='ANALYST';
SET CURRENT EXPLAIN MODE NO;

使用 db2exfmt 工具查看查詢執行計劃: db2exfmt -d <DBNAME> -1 -g -o <FILENAME>

使用您喜愛的文本編輯器,您應看到像下面這樣的查詢執行計劃:     2
   TBSCAN
   (  2)
   30.8464
    2
    |
    32
TABLE: SKAPOOR
  EMPLOYEE

基數估計值 2 符合實際結果。

為這個查詢添加幾個冗余的等式謂詞 : SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
FROM EMPLOYEE
WHERE JOB='ANALYST' AND SEX='F' AND WORKDEPT='C01';

此查詢返回和上面相同的結果集。但是看一下 EXPLAIN 工具生成的查詢執行計劃,基數估計值並不符合實際結果:

  0.0761719
   TBSCAN
   (  2)
   31.4115
    2
    |
    32
TABLE: SKAPOOR
  EMPLOYEE

DB2 優化器假設這三個謂詞是彼此獨立的,因為不存在相關的索引或列組統計信息。

在 JOB、WORKDEPT 和 SEX 列中收集列組統計信息。 RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE ON ALL COLUMNS AND COLUMNS
  ((JOB, WORKDEPT, SEX)) WITH DISTRIBUTION;

使用這三個列的列組統計信息,DB2 優化器計算出一個更准確的基數估計值:

   1.77778
   TBSCAN
   (  2)
   31.4214
    2
    |
    32
TABLE: SKAPOOR
  EMPLOYEE

與單一謂詞查詢計算出的結果不同,所計算出的基數估計值並不是 2,這是因為列組統計信息是一個一致分布統計信息。

示例 4:等式連接謂詞

這個示例集中關注表 ORG 和 STAFF 的連接。首先,需要在這兩個表上收集統計信息。現在,已經收集好了基本的統計信息。

RUNSTATS ON TABLE <SCHEMA_NAME>.ORG;
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF;

下面的查詢連接 ORG 和 STAFF 表:

SELECT STAFF.NAME, ORG.DEPTNUMB, ORG.DEPTNAME, STAFF.SALARY
FROM ORG, STAFF
WHERE ORG.MANAGER = STAFF.ID AND ORG.DEPTNUMB = STAFF.DEPT
ORDER BY ORG.DEPTNUMB;

這個查詢返回 8 個記錄:

NAME   DEPTNUMB DEPTNAME    SALARY 
--------- -------- -------------- ---------
Molinare    10 Head Office   22959.20
Hanes      15 New England   20659.80
Sanders     20 Mid Atlantic  18357.50
Marenghi    38 South Atlantic 17506.75
Plotz      42 Great Lakes   18352.80
Fraye      51 Plains     21150.00
Lea       66 Pacific     18555.50
Quill      84 Mountain    19818.00
 8 record(s) selected.

使用 EXPLAIN 工具查看查詢執行計劃:         1
       TBSCAN
       (  2)
       33.2225
        2
        |
        1
       SORT 
       (  3)
       33.151
        2
        |
        1
       HSJOIN
       (  4)
       33.0248
        2
     /-----+-----
    35        8
   TBSCAN      TBSCAN
   (  5)      (  6)
   17.2334     15.3736
    1        1
    |        |
    35        8
TABLE: SKAPOOR TABLE: SKAPOOR
   STAFF       ORG

這個示例使用了收集列組統計信息的簡單方法。附錄 B 包含一些示例,對判定連接中的父表做了進一步的分析。

對 STAFF 表的 ID、DEPT 列和 ORG 表的 MANAGER、DEPTNUMB 列做了連接,所以要在這兩組列中收集列組統計信息: RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF ON ALL COLUMNS AND COLUMNS ((ID, DEPT));
RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS AND COLUMNS ((MANAGER, DEPTNUMB));

DB2 優化器使用收集到的列組統計信息正確地估計了基數:

        8
       TBSCAN
       (  2)
       33.5658
        2
        |
        8
       SORT 
       (  3)
       33.4243
        2
        |
        8   
       HSJOIN
       (  4)
       33.0363
        2
     /-----+-----
    35        8
   TBSCAN      TBSCAN
   (  5)      (  6)
   17.2334     15.3736
    1        1
    |        |
    35        8
TABLE: SKAPOOR TABLE: SKAPOOR
   STAFF       ORG

示例 5:查看多列統計信息

優化器利用兩種類型的多列統計信息:索引 keycard 統計信息和列組統計信息。這個示例提供了查看表中可用多列統計信息的步驟。

選項 1. 使用 db2look 工具

db2look 工具用來生成 DDL 語句,從而重新創建數據庫中定義的對象。可以使用 -m 選項來顯示為這些對象收集的統計信息。

在 ORG 表中收集列組統計信息和索引統計信息: CREATE INDEX IX1 ON ORG (DEPTNUMB, DEPTNAME, MANAGER);
RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS
     AND COLUMNS ((DEPTNUMB, DEPTNAME, MANAGER, DIVISION, LOCATION))
     WITH DISTRIBUTION AND INDEXES ALL;

使用 db2look 工具查看 ORG 表的統計信息: db2look -d sample -e -a -m -t ORG -o org.ddl

注意:使用 -h 選項查看關於 DB2look 工具的信息。

在 org.ddl 文件中查看輸出。它應該包含如下用於列組統計信息的 UPDATE 語句: UPDATE SYSSTAT.COLGROUPS SET colgroupcard = 8
    WHERE colgroupid IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
       AND colname = 'DEPTNUMB' AND oridnal = 1)
    AND colgroupid IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
       AND colname = 'DEPTNAME' AND oridnal = 2)
    AND colgroupid IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
       AND colname = 'MANAGER' AND oridnal = 3)
    AND colgroupid IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
       AND colname = 'DIVISION' AND oridnal = 4)
    AND colgroupid IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
       AND colname = 'LOCATION' AND oridnal = 5)
    AND colgroupid NOT IN (SELECT colgroupid
    FROM SYSCAT.COLGROUPCOLS
    WHERE tabschema = 'SKAPOOR '
       AND tabname = 'ORG' AND oridnal = 6) ;

注意:在 V8 FixPak 13 中,列組統計信息添加到了 db2look 工具中。

上面的 update 語句列出了 SYSCAT.COLGROUPCOLS 視圖的所有列,以及來自 SYSSTAT.COLGROUPS 的相關多列統計信息,它表示列集中不同組的數量。在這個示例中,以上的語句描述了列集(DEPTNUMB、DEPTNAME、MANAGER、DIVISION 和 LOCATION)具有八個不同的組。

org.ddl 文件也包含如下用於索引統計信息的語句:

UPDATE SYSSTAT.INDEXES
SET NLEAF=1,
  NLEVELS=1,
  FIRSTKEYCARD=8,
  FIRST2KEYCARD=8,
  FIRST3KEYCARD=8,
  FIRST4KEYCARD=-1,
  FULLKEYCARD=8,
  CLUSTERFACTOR=-1.000000,
  CLUSTERRATIO=100,
  SEQUENTIAL_PAGES=0,
  DENSITY=0,
  AVERAGE_SEQUENCE_GAP=0.000000,
  AVERAGE_SEQUENCE_FETCH_GAP=0.000000,
  AVERAGE_SEQUENCE_PAGES=0.000000,
  AVERAGE_SEQUENCE_FETCH_PAGES=0.000000,
  AVERAGE_RANDOM_PAGES=1.000000,
  AVERAGE_RANDOM_FETCH_PAGES=0.000000,
  NUMRIDS=8,
  NUMRIDS_DELETED=0,
  NUM_EMPTY_LEAFS=0
WHERE INDNAME = 'IX1' AND INDSCHEMA = 'SKAPOOR'
   AND TABNAME = 'ORG' AND TABSCHEMA = 'SKAPOOR';

以上的 update 語句描述了下列多列統計信息。FIRST2KEYCARD 統計信息描述了列(DEPTNUMB,DEPTNAME)中不同組的數量,FIRST3KEYCARD 和 FULLKEYCARD 描述了完整列集(DEPTNUMB,DEPTNAME,MANAGER)中不同組的數量。FIRST4KEYCARD 的值為 -1,這是因為索引在該鍵中只有 3 列。

選項 2. 查詢目錄表

可以從 DB2 目錄表中查詢與 DB2look 工具輸出中所描述的相同的信息。

如果尚未創建索引,請按選項 1 中的步驟 1 創建索引,在多個表中收集多個列組統計信息: RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS
     AND COLUMNS ((DEPTNUMB, DEPTNAME, MANAGER, DIVISION, LOCATION),
     (DEPTNUMB, DEPTNAME), (MANAGER, DIVISION)) WITH DISTRIBUTION AND INDEXES ALL;
RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE ON ALL COLUMNS
     AND COLUMNS ((EMPNO, WORKDEPT), (EMPNO, WORKDEPT, JOB));

查詢目錄表來檢索列組統計信息。注意下面的查詢是一個遞歸 SQL 語句,它會導致一個可以忽略的 SQL0347W 警告。可以使用 “UPDATE COMMAND OPTIONS USING W OFF” 選項阻止該警告出現。 WITH TMP(ID, NUM) AS
(
  SELECT COLGROUPID, MAX(ORIDNAL)
   FROM SYSCAT.COLGROUPCOLS
  GROUP BY COLGROUPID
),
TMP2 (ID, NAME, NUM, TNAME, TSCHEMA) AS
(
  SELECT ID, CAST(RTRIM(COLNAME) AS CHAR(128)), NUM, TABNAME, TABSCHEMA
   FROM TMP Y, SYSCAT.COLGROUPCOLS X
  WHERE X.COLGROUPID = Y.ID
   AND Y.NUM = X.ORIDNAL
 UNION ALL
  SELECT Y.ID, CAST(RTRIM(X.COLNAME) || ',' || Y.NAME AS CHAR(128)), Y.NUM-1,
     TNAME, TSCHEMA
   FROM TMP2 Y, SYSCAT.COLGROUPCOLS X
  WHERE Y.ID=X.COLGROUPID
   AND X.ORIDNAL=Y.NUM-1
   AND Y.NUM > 1
   AND TNAME = TABNAME
   AND TSCHEMA = TABSCHEMA
)
SELECT SUBSTR(TSCHEMA,1,10) TABSCHEMA, SUBSTR(TNAME,1,10) TABNAME,
  NAME COLS, COLGROUPCARD
FROM TMP2, SYSSTAT.COLGROUPS
WHERE ID = COLGROUPID
AND NUM = 1
ORDER BY TABSCHEMA, TABNAME
;

上面的查詢返回如下記錄:

注意:TABSCHEMA 列中的值將是不同的。同樣,COLS 結果列並強制轉換為 CHAR(128),如果結果超過 128 個字符,它會將結果截斷。在這個例子中,可能需要將 CAST 修改為一個更大的字符串。

TABSCHEMA TABNAME  COLS                  COLGROUPCARD    
---------- ---------- ------------------------------//------ -----------------
SKAPOOR  EMPLOYEE  EMPNO,WORKDEPT                    32
SKAPOOR  EMPLOYEE  EMPNO,WORKDEPT,JOB                  32
SKAPOOR  ORG    DEPTNUMB,DEPTNAME                   8
SKAPOOR  ORG    MANAGER,DIVISION                    8
SKAPOOR  ORG    DEPTNUMB,DEPTNAME,MANAGER,DIVISION,LOCATION      8
 5 record(s) selected with 1 warning messages suppressed.

這些記錄描述了 EMPLOYEE 表的兩列組統計信息和 ORG 表的三列組統計信息。

注意:在上面的查詢中,注意 SYSCAT.SYSCOLGROUPCOLS 視圖中的名為 “ORIDNAL” 的列。在 DB2 9 中,其拼寫改為了 “ORDINAL”,所以,這個查詢需要按照在 DB2 9 中使用的方法更新,如下所示:

WITH TMP(ID, NUM) AS
(
  SELECT COLGROUPID, MAX(ORDINAL)
   FROM SYSCAT.COLGROUPCOLS
  GROUP BY COLGROUPID
),
TMP2 (ID, NAME, NUM, TNAME, TSCHEMA) AS
(
  SELECT ID, CAST(RTRIM(COLNAME) AS CHAR(128)), NUM, TABNAME, TABSCHEMA
   FROM TMP Y, SYSCAT.COLGROUPCOLS X
  WHERE X.COLGROUPID = Y.ID
   AND Y.NUM = X.ORDINAL
 UNION ALL
  SELECT Y.ID, CAST(RTRIM(X.COLNAME) || ',' || Y.NAME AS CHAR(128)), Y.NUM-1,
     TNAME, TSCHEMA
   FROM TMP2 Y, SYSCAT.COLGROUPCOLS X
  WHERE Y.ID=X.COLGROUPID
   AND X.ORDINAL=Y.NUM-1
   AND Y.NUM > 1
   AND TNAME = TABNAME
   AND TSCHEMA = TABSCHEMA
)
SELECT SUBSTR(TSCHEMA,1,10) TABSCHEMA, SUBSTR(TNAME,1,10) TABNAME, NAME COLS,
   COLGROUPCARD
FROM TMP2, SYSSTAT.COLGROUPS
WHERE ID = COLGROUPID
AND NUM = 1
ORDER BY TABSCHEMA, TABNAME
;

查詢目錄表以檢索索引統計信息。

注意:在 TABSCHEMA='SKAPOOR' 謂詞中使用合適的模式名替換所提供的值。

SELECT SUBSTR(COLNAMES, 1, 30) AS COLS, FIRST2KEYCARD, FIRST3KEYCARD,
   FIRST4KEYCARD, FULLKEYCARD
FROM SYSSTAT.INDEXES
WHERE TABSCHEMA='SKAPOOR' AND TABNAME='ORG';

上述查詢返回如下記錄:

COLS            FIRST2KEYCARD FIRST3KEYCARD FIRST4KEYCARD FULLKEYCARD
-------------------------- ------------- ------------- ------------- -----------
+DEPTNUMB+DEPTNAME+MANAGER       8       8      -1      8
 1 record(s) selected.

FIRST2KEYCARD 統計信息描述了在列(DEPTNUMB 和 DEPTNAME)中不同組的數量,FIRST3KEYCARD 和 FULLKEYCARD 描述了完整列集(DEPTNUMB,DEPTNAME 和 MANAGER)中不同組的數量。FIRST4KEYCARD 值為 -1,這是因為索引在鍵中只包含三列。

練習

在示例 3 和 4 中,優化器使用了索引統計信息,而沒有使用列組統計信息,通過說明統計信息相關性來修正基數估計值。

嘗試以下步驟:

創建如下索引: IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX);
IXSTAFF_1 ON STAFF(ID, DEPT);
IXORG_1 ON ORG(MANAGER, DEPTNUMB);

對這些索引收集統計信息,但不收集任何列組統計信息: RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE AND INDEXES ALL;
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF AND DETAILED INDEXES ALL;
RUNSTATS ON TABLE <SCHEMA_NAME>.ORG AND INDEXES ALL;

對示例 3 和 4 中的查詢進行 EXPLAIN 處理。所得到的基數估計值符合上面的查詢執行計劃;然而,由於可用索引的不同,實際的計劃會有所不同。注意收集的 DETAILED 統計信息並不影響基數估計值。

丟棄步驟 1 中創建的 IXEMP_1 和 IXSTAFF_1 索引,創建兩個新的索引: IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX, EMPNO);
IXSTAFF_1 ON STAFF(ID, DEPT,NAME,JOB);

重復步驟 2 和步驟 3。其最後的基數估計值是相同的。

附錄 A. 自動統計信息分析

RUNSTATS 實用程序提供了一個選項,用它可以注冊和使用一個統計信息配置文件。DB2 的自動統計信息分析特性可以自動地生成統計信息配置文件。啟用了這個特性後,將會收集有關數據庫活動的信息並將其存儲在查詢反饋倉庫中。在這些數據的基礎之上,生成一個統計信息配置文件。該特性還會推薦對本地等式謂詞使用兩列組統計信息。這在測試環境中是一種游泳的工具,可標識有用的列組統計信息。

Info Center 中包含關於使用 自動統計信息分析 的更詳細信息。.

注意:統計信息配置文件的自動生成只在 DB2 串行模式中是激活的,在聯邦查詢、DPF 環境之中以及使用分區內並行性時,該特性是被禁止的。

附錄 B. 確定兩個連接表中的父表

多個等式謂詞的統計相關性 一節中討論了一種簡單方法,通過說明等式連接謂詞間的統計相關性而收集多列統計信息,這一節將介紹優化器如何確定兩個連接表中的父表(如果有的話)。鑒別優化器是否會檢測一個父表,如果會的話,哪一個是父表,這對於了解何時進行列組統計信息的收集才是有效的以及在哪個表上收集是非常有用的。

優化器在一組連接兩表的謂詞中標識父表,這個表至少是一個連接謂詞的父表,而且不是任何其他連接謂詞的子表。一個連接謂詞的父表被確定為在謂詞列中具有較多不同值的表。例如,在 SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID 連接謂詞中,如果 SHOW_LISTINGS.SHOW_ID 的 COLCARD 統計信息比 RATINGS.SHOW_ID 的 COLCARD 統計信息多,那麼 SHOW_LISTINGS 就是這個連接謂詞的父表,RATINGS 則是子表。

此外,優化器還嘗試使用范圍統計信息(HIGH2KEY 和 LOW2KEY)來驗證父表,方法是確保子表中的值集是父表的子集。例如,在連接謂詞 SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID 中,如果符合以下條件:

SHOW_LISTINGS.SHOW_ID 的 COLCARD 統計信息多於 RATINGS.SHOW_ID 的統計信息,並且

SHOW_LISTINGS.SHOW_ID 的 HIGH2KEY 多於或等於 RATINGS.SHOW_ID 的 HIGH2KEY,並且

RATINGS.SHOW_ID 的 LOW2KEY 少於或等於 RATINGS.SHOW_ID 的 LOW2KEY

那麼 SHOW_LISTINGS 是這個連接謂詞的父表,而 RATINGS 則是子表。

示例 B.1

假設以下一組謂詞:

P1: SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID
P2: SHOW_LISTINGS.CHANNEL_ID = RATINGS.CHANNEL_ID
P3: SHOW_LISTINGS.STATION_ID = RATINGS.STATION_ID

在 P1 中,假設 COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。

在 P2 中,假設 COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID)。

在 P3 中,假設 COLCARD(SHOW_LISTINGS.STATION_ID) > COLCARD(RATINGS.STATION_ID)。

優化器將 SHOW_LISTINGS 表標識為所有三個謂詞的父表,所以它同樣將 SHOW_LISTINGS 標識為連接的父表。因此優化器使用 SHOW_LISTINGS 表中的列(SHOW_ID,CHANNEL_ID 和 STATION_ID)上可用的多列統計信息。

示例 B.2

使用示例 B.1 中的謂詞:

在 P1 中,假設 COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。

在 P2 中,假設 COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID)。

在 P3 中,假設 COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID)。

優化器在謂詞 P1 和 P2 中將 SHOW_LISTINGS 表標識為父表,在謂詞 P3 中既不是子表,也不是父表。所以優化器也將 SHOW_LISTINGS 標識為連接的父表。因此,優化器使用 SHOW_LISTINGS 表中的列(SHOW_ID,CHANNEL_ID 和 STATION_ID)上可用的多列統計信息。

示例 B.3

使用示例 B.1 中的謂詞:

在 P1 中,假設 COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。

在 P2 中,假設 COLCARD(SHOW_LISTINGS.CHANNEL _ID) < COLCARD(RATINGS.CHANNEL_ID)。

在 P3 中,假設 COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID)。

優化器在謂詞 P1 中將 SHOW_LISTINGS 表標識為父表,在謂詞 P2 中將其標識為子表,在謂詞 P3 中既不是子表也不是父表。所以,並不將 SHOW_LISTINGS 標識為連接中的父表(也不將 RATINGS 標識為連接的父表)。因此,優化器並不會檢測這三個連接的謂詞間的統計相關性。

數據庫分區特性

在一個 DPF 環境中,如果表跨多個數據庫分區而被分區,在下列條件滿足的情況下,只能使用范圍統計信息:

兩個表在相同的列中被分區

表是並置的,就是說,它們處於同一節點組

連接謂詞引用所有的分區鍵列

在相同的節點收集統計信息

如果不能夠使用范圍統計信息,那麼優化器只能使用 COLCARD 統計信息來確定連接中的父表。在 DPF 環境中,在單個節點中收集統計信息將會導致在 COLCARD 統計信息出現錯誤。因此,確定父表時,優化器允許 COLCARD 統計信息中存在一些偏差(1%)。然而,這種偏差是以多列統計信息為基礎的,因此如果該連接不是中立 的,並且連接中沒有很明顯的父表,那麼在 DPF 中應該使用收集列組統計信息的簡單方法。

示例 B.4

1. 確定兩個表是否在相同列上被分區

除非兩個表的數據分布相同,否則不能使用范圍統計信息(HIGH2KEY 和 LOW2KEY)。因此,如果表不是在相同列被分區,優化器將無法推斷出數據在兩個表中的分布相同。

假設有兩個表,T1 和 T2。T1 在多個數據庫分區中被分區,在列(C1 和 C2)中具有分區鍵。同樣,T2 也進行了分區,其分區鍵在列(C2 和 C3)中。

例 1.1 使用下列謂詞連接 T1 和 T2:

P1: T1.C1=T2.C2
P2: T1.C2=T2.C3

這兩個表被認為是在相同的列進行了分區,因為連接謂詞按照與其各自的分區鍵相同的次序應用於列中。

例 1.2 使用下列謂詞:

P1: T1.C1=T2.C3
P2: T1.C2=T2.C2

謂詞沒有按照與其各自的分區鍵相同的次序應用於列中,所以這兩個表被認為不是在相同列上分區的。

例 1.3 使用下列謂詞:

P1: T1.C1=T2.C1
P2: T1.C2=T2.C2
P3: T1.C3=T2.C3

這些表被認為不是在相同列分區的。

例 1.4 來看一下和示例 1.3 使用相同謂詞的情形,但是假設 T2 是在列(C1,C2 和 C3)中分區的。

盡管表 T1 是在相同列分區的(T2 分區鍵的兩個主要列),由於 T2 在 C3 中進一步分區,與只在(C1 和 C2)中分區相比,這將導致數據分布不同。因此,這兩個表被認為是在不同列進行分區的。

2. 確定這兩個表是否是並置的

假設有兩個表,T1 和 T2,T1 屬於節點組 N0 而 T2 屬於節點組 N1,其中 N0 包含分區數 0 和 1 ,N1 包含分區數 1 和 2 。由於這兩個表不在同一個節點組,將認為它們不是並置的。

3. 確定連接的謂詞是否引用所有的分區鍵列

假設有兩個表,T1 和 T2。T1 在多個數據庫分區中被分區,分區鍵在列(C1 和 C2)。同樣,T2 也被分區,分區鍵在列(C2 和 C3)。

3.1 使用這些謂詞來連接 T1 和 T2:

P1: T1.C1=T2.C2
P2: T1.C2=T2.C3

這兩個謂詞都包含了所有的分區鍵列。

例 3.2 如果在示例 3.1 謂詞中添加第三個謂詞 P3,T1.C3=T2.C1,那麼這三個謂詞合起來仍然包含兩個表中的所有分區鍵列。然而,如果僅使用 P1 和 P3,所有這三個謂詞並不包含分區鍵列。

例 3.3如果在示例 3.1 謂詞中添加第三個謂詞 P3,T1.C3=T2.C3,那麼這三個謂詞合起來仍然包含兩個表中的所有分區鍵列。然而,如果只使用P1 和 P3,那麼只包含了 T2 的分區鍵列而沒有包含 T1 的,所以條件並不符合。

完全限定的惟一索引

如果在上述條件的基礎上,沒有一個表被指定為連接的父表,優化器將進一步檢查一個完全限定的惟一索引。如果連接謂詞完全限定一個惟一索引,優化器使用惟一索引的 FULLKEYCARD 統計信息來檢測和說明相等連接謂詞之間的統計相關性。

中立連接

如果未在兩個表間的任一等式連接謂詞中標識出父表,優化器將把這個連接標識為中立(neutral)。如果兩個列的 COLCARD 相同,並且它們包含的值的范圍也是相同的(HIGH2KEY 和 LOW2KEY 統計信息是等同的),則不對這個等式連接謂詞標識父表。

在 DB2 V8 的 FixPaks 13 及更早版本中,如果是一個中立的 NPK 連接,優化器就不會為兩個表的連接說明一組等式連接謂詞間的統計相關性。在 V8 FixPak 14 和 DB2 9 中,優化器的統計相關性檢測得到了擴展,可以對中立的 NPK 連接進行統計相關性說明。

兩個表引用相同的基表,這種自連接是中立連接的特例。在 V8.2 中,優化器開始為這種特例說明統計相關性。

示例 B.5:在父表中收集列組統計信息

這個例子主要關注表 ORG 和 STAFF 間的連接。首先,需要為表收集統計信息。現在,已經收集了基本的統計信息:

RUNSTATS ON TABLE <SCHEMA_NAME>.ORG;
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF;

假設如下查詢連接表 ORG 和 STAFF:

SELECT STAFF.NAME, ORG.DEPTNUMB, ORG.DEPTNAME, STAFF.SALARY
FROM ORG, STAFF
WHERE ORG.MANAGER = STAFF.ID AND ORG.DEPTNUMB = STAFF.DEPT
ORDER BY ORG.DEPTNUMB;

這個查詢返回 8 個記錄:

NAME   DEPTNUMB DEPTNAME    SALARY 
--------- -------- -------------- ---------
Molinare    10 Head Office   22959.20
Hanes      15 New England   20659.80
Sanders     20 Mid Atlantic  18357.50
Marenghi    38 South Atlantic 17506.75
Plotz      42 Great Lakes   18352.80
Fraye      51 Plains     21150.00
Lea       66 Pacific     18555.50
Quill      84 Mountain    19818.00
8 record(s) selected.

1. 使用 EXPLAIN 工具,查看查詢執行計劃:

        1
       TBSCAN
       (  2)
       33.2225
        2
        |
        1
       SORT 
       (  3)
       33.151
        2
        |
        1
       HSJOIN
       (  4)
       33.0248
        2
     /-----+-----
    35        8
   TBSCAN      TBSCAN
   (  5)      (  6)
   17.2334     15.3736
    1        1
    |        |
    35        8
TABLE: SKAPOOR TABLE: SKAPOOR
   STAFF       ORG
   

2. 查看連接謂詞引用的列的列統計信息。如下查詢為兩個連接謂詞中引用的表 ORG 和 STAFF 中的列從 DB2 目錄表中檢索有趣的列統計信息:

SELECT SUBSTR(COLNAME,1,20) AS COLNAME, COLCARD,
    SUBSTR(HIGH2KEY,1,10) AS HIGH2KEY,
    SUBSTR(LOW2KEY,1,10) AS LOW2KEY
FROM SYSSTAT.COLUMNS
WHERE TABNAME IN ('ORG', 'STAFF')
AND COLNAME IN ('MANAGER', 'DEPTNUMB', 'ID', 'DEPT')
ORDER BY TABNAME, COLNAME;

表 B.5 列統計信息

COLNAME COLCARD HIGH2KEY LOW2KEY DEPTNUMB 8 66 15 MANAGER 8 270 30 DEPT 8 66 15 ID 35 340 20

3. 計算基數估計值。

等式連接謂詞的過濾因子的估計值計算如下:

1/max(colcard_LHS,colcard_RHS).

其中 LHS 在連接謂詞的左邊,RHS 在連接謂詞的右邊。本例中有以下兩個連接謂詞:

P1: org.manager=staff.id
P2: org.deptnumb=staff.dept

以及過濾因子(ff),P1 和 P2 計算如下:

ff(P1) = 1 / max (8,35) = 1/35 = 0.0285714
ff(P2) = 1/max(8,8) = 1/8 = 0.125

使用過濾因子以及兩個表的基數估計值,連接基數計算如下:

JoinCard = Cardinality(ORG) * cardinality(STAFF) * ff(P1) * ff(P2)
     = 35 * 8 * 0.0285714 * 0.125
     = 1

4. 在連接中標識父表。

在表 B.5 中,列統計信息顯示 STAFF 是連接的父表,因為符合以下條件:

對於謂詞 org.manager=staff.id:

colcard(MANAGER) < colcard(ID)
high2key(MANAGER) < high2key(ID)
low2key(MANAGER) > low2key(ID)

因此,這個謂詞的父表是 STAFF。

對於謂詞 org.deptnumb=staff.dept,colcard、high2key 和 low2key 統計信息是等同的。因此,這個謂詞不存在父表,它應被視為“中立”。

5. 在父表中收集列組統計信息。

在步驟 4 中,STAFF 被標識為連接的父表,ORG 被標識為連接的子表,所以應在 STAFF 表的列(ID,DEPT)中收集列組統計信息:

RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF ON ALL COLUMNS AND COLUMNS ((ID,DEPT));

使用這兩個列的列組統計信息,DB2 優化器就可以准確地估計出基數:

        8 
       TBSCAN
       (  2)
       33.5658
        2
        |
        8
       SORT 
       (  3)
       33.4243
        2
        |
        8
       HSJOIN
       (  4)
       33.0363
        2
     /-----+-----
    35        8
   TBSCAN      TBSCAN
   (  5)      (  6)
   17.2334     15.3736
    1        1
    |        |
    35        8
TABLE: SKAPOOR TABLE: SKAPOOR
   STAFF       ORG

示例 B.6 中立連接

考慮 T1 和 T2 這兩個表的連接,使用以下謂詞:

  
P1: T1.C1 = T2.C1
P2: T1.C2 = T2.C2
P3: T1.C3 = T2.C3

假設這兩個表具有以下的統計信息:


表 B.6 中立連接統計信息

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY T1 C1 100 99 2 T2 C1 100 99 2 T1 C2 10 1999 1900 T2 C2 10 1999 1900 T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'

所有的謂詞被看作是中立的,這是由於兩個表的 stats 是相等的。因此,在 V8 FixPak 14 和 DB2 9 中,應該在任一個表(不要求兩個表)的列(C1、C2 和 C3)中收集列組統計信息,這樣,優化器就可以檢測這些連接謂詞的統計相關性。

示例 B.7

使用和示例 B.6 相同的謂詞,假設表具有如下統計信息:


表 B.7 確定父表

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY T1 C1 100 99 2 T2 C1 10 99 2 T1 C2 10 1999 1900 T2 C2 10 1999 1900 T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'

在這個場景中,謂詞 P2 和 P3 看作是中立的,這是由於兩個表的列 C2 和 C3 的統計信息是等同的。然而,C1 的統計信息顯示 T1 是 P1 的父表,這是因為 T1.C1 的 COLCARD 比 T2.C1 的 COLCARD 大,並且兩個列具有等同的 HIGH2KEY 和 LOW2KEYare 統計信息。因此,應該在 T1 的列(C1、C2 和 C3)中收集列組統計信息,這樣,優化器就可以檢測連接謂詞間的統計相關性。

示例 B.8

使用和示例 B.6 相同的謂詞,假設表具有下列統計信息:


表 B.8 統計信息

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY T1 C1 100 99 2 T2 C1 10 999 2 T1 C2 10 1999 1900 T2 C2 10 1999 1900 T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'

在這個場景中,謂詞 P2 和 P3 被表示為中立的,這是由於兩個表的 C2 和 C3 列的統計信息是等同的。然而,C1 的統計信息表明 T1 和 T2 都不是父表,它也不是中立的,因為 T1.C1 具有一個更高的 COLCARD 統計信息,而 T2.C1 具有一個更高的統計信息。因此,應該在 T1 或 T2 的列(C2 和 C3)中收集列組統計信息,這樣優化器就可以檢測連接謂詞 P2 和 P3 之間的統計相關性。

示例 B.9 使用 DPF 和范圍統計信息

考慮 T1 和 T2 這兩個表的連接,它們在多個數據庫分區上被分區,並且是並置的,統計信息是在相同的節點手機的,分區鍵在列(C1 和 C2)上,使用如下謂詞進行連接:

  
P1: T1.C1 = T2.C1
P2: T1.C2 = T2.C2
P3: T1.C3 = T2.C3

假設這兩個表具有如下統計信息:


表 B.9

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY T1 C1 100 99 2 T2 C1 10 999 2 T1 C2 10 1999 1900 T2 C2 10 1999 1900 T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'

這個連接限定 DPF 條件,所以優化器可以使用范圍統計信息來標識父表。在這個場景中,謂詞 P2 和 P3 被表示為中立,這是由於兩個表的 C2 和 C3 列的統計信息是等同的。然而,C1 的統計信息表明 T1 和 T2 都不是父表,也不把它看作是中立的,這是因為 T1.C1 具有一個更高的 COLCARD,而 T2.C1 具有一個更高的 HIGH2KEY 統計信息。因此,應該在 T1 或 T2 的列(C2 和 C3)上收集列組統計信息,這樣優化器就可以檢測連接謂詞 P2 和 P3 間的統計相關性。

示例 B.10 無法使用 DPF 和范圍統計信息

假設與 B.9 相同的場景,但是 T1 的分區鍵是在列(C1 和 C2)中,T2 的分區鍵在列(C2 和 C1)中。這個連接不滿足第一個 DPF 條件,因為這兩個表被認為不是在相同的列分區的;連接謂詞 T1.C1=T2.C1 在 T1 的分區鍵中引用了第一個列,但在 T2 分區鍵中引用了第二個列。因此,優化器不能使用范圍統計信息來標識父表,而只能使用 COLCARD 統計信息來確定父表。只在 COLCARD 的基礎上,連接被認為是中立的。

示例 B.10.1 無法使用 DPF 和范圍統計信息

假設與 B.10 相同的場景,但具有下列統計信息:


表 B.10

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY T1 C1 100 99 2 T2 C1 98 999 2 T1 C2 10 1999 1900 T2 C2 11 1999 1900 T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'

在 COLCARD 統計信息基礎上,T1 是謂詞 P1 的父表,而 T2 是謂詞 P2 的父表。由於 COLCARD 統計信息被關閉,因此多列統計信息的偏差將降至 1% 以內,這是優化器在 DPF 環境中的容錯值。在這裡它可以使用簡單方法,並且應在兩個表的所有三個列中收集列組統計信息。之後,如果優化器沒有計算出一個不同的基數估計值,那麼說明並未達到 1% 的偏差。

附錄 C. 有關本地謂詞的更多詳細資料

多列統計信息(索引和列組)只提供了一組列中不同組數量的信息。因此,說明統計相關性時,優化器假設數據是一致分布的。然而,本地等式謂詞的選擇性估計值則使用分布統計信息(如果可用)來計算,從而說明數據中的偏差。由於假設數據是一致的,而實際上數據是有偏差的,為避免高估本地等式謂詞的組合選擇性估計值,FixPak 10 中將對優化器的統計相關性檢測做進一步改善。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved