理解 DB2 中列組統(tǒng)計(jì)信息
簡介
DB2 SQL 優(yōu)化器(后文簡稱為優(yōu)化器)可以估計(jì)每個(gè)備選訪問計(jì)劃的執(zhí)行成本,并根據(jù)其估計(jì)結(jié)果選擇一個(gè)最佳訪問計(jì)劃。一個(gè)訪問計(jì)劃可以指定用來解析一條 SQL 語句的操作次序。
為正確地確定每種訪問計(jì)劃的成本,DB2 優(yōu)化器需要準(zhǔn)確的基數(shù)估計(jì)值。基數(shù)估計(jì)是這樣一種過程:在應(yīng)用了謂詞或執(zhí)行了聚集之后,優(yōu)化器使用統(tǒng)計(jì)信息確定部分查詢結(jié)果的大小。對(duì)于訪問計(jì)劃的每個(gè)操作符,優(yōu)化器將估計(jì)該操作符的基數(shù)輸出。一個(gè)或更多謂詞的應(yīng)用可以減少輸出流基數(shù)。
在計(jì)算謂詞對(duì)于基數(shù)估計(jì)值的組合過濾效果時(shí),通常會(huì)假設(shè)這些謂詞彼此之間是獨(dú)立的。然而,這些謂詞可以在統(tǒng)計(jì)方面彼此關(guān)聯(lián)。單獨(dú)地處理它們通常會(huì)導(dǎo)致優(yōu)化器低估基數(shù)值。而基數(shù)值的低估又會(huì)導(dǎo)致優(yōu)化器選擇一個(gè)次優(yōu)的訪問計(jì)劃。
對(duì)于至少應(yīng)用了至少兩個(gè)本地等式謂詞的 SQL 語句,優(yōu)化器將考慮使用多列統(tǒng)計(jì)信息來檢測統(tǒng)計(jì)關(guān)聯(lián),并更加準(zhǔn)確地估計(jì)多個(gè)謂詞組合的過濾效果。同樣對(duì)于連接兩個(gè)或更多表的 SQL 語句,以及在一對(duì)表間至少使用了兩個(gè)等式連接謂詞的連接,優(yōu)化器也會(huì)使用多列統(tǒng)計(jì)信息。
一個(gè)本地等式謂詞是一個(gè)應(yīng)用于單個(gè)表的等式謂詞,其描述如下所示:
其中 literal 可以是以下任一內(nèi)容:
一個(gè)常量值;
一個(gè)參數(shù)標(biāo)記或一個(gè)主變量;
一個(gè)專用寄存器(例如,CURRENT DATE)
一個(gè)等式連接謂詞的描述如下所示,它用于表 1 和表 2 間的連接:
DB2 V8.2 使用下面的多列統(tǒng)計(jì)信息:
索引 keycard 統(tǒng)計(jì)信息:FIRST2KEYCARD、FIRST3KEYCARD、FIRST4KEYCARD 和 FULLKEYCARD
列組統(tǒng)計(jì)信息:列組基數(shù)值
這些統(tǒng)計(jì)信息描述了包含兩個(gè)或更多列的列集中不同分組的數(shù)量。
在 DB2 V8.2 出現(xiàn)之前,只能使用索引 keycard 統(tǒng)計(jì)信息,并且要受下列條件約束:
索引必須是完全限定的。假如鍵中的所有列都可以被等式謂詞 引用(連接謂詞或本地謂詞,但不是兩者的混合),那么這個(gè)索引就是完全限定的。 對(duì)于連接謂詞,索引也必須是惟一的。
在 DB2 V8.2 中,通過考慮到所有索引 keycard 統(tǒng)計(jì)信息而不要求索引完全限定,DB2 SQL 優(yōu)化器進(jìn)一步擴(kuò)展了多列統(tǒng)計(jì)信息的使用。它還考慮到了用戶收集的任何列組統(tǒng)計(jì)信息。本文討論了優(yōu)化器如何利用這些統(tǒng)計(jì)信息,以及用戶如何識(shí)別要收集的列組統(tǒng)計(jì)信息。
多個(gè)本地等式謂詞的統(tǒng)計(jì)相關(guān)性
DB2 SQL 優(yōu)化器試圖檢測多個(gè)本地等式謂詞間的統(tǒng)計(jì)相關(guān)性。
示例 1:假設(shè)有一個(gè)表 SHOW_LISTINGS,它包含如下列: 表 1. SHOW_LISTINGS 表的描述
列名 描述SHOW_ID 表外鍵,包含關(guān)于各演出清單的信息CHANNEL_ID 表外鍵,包含關(guān)于播放演出的每個(gè)頻道的信息STATION_ID 表外鍵,包含和頻道相關(guān)的每個(gè)電視臺(tái)的信息CITY_ID 表外鍵,包含關(guān)于上演該演出的每個(gè)城市的信息DAY 演出播放的日期TIME 演出播放的當(dāng)天的時(shí)間<other columns> 描述了演出清單的其他屬性由于演出只在某個(gè)電視臺(tái)的某個(gè)頻道播出,在一天的特定時(shí)間內(nèi),這些列(SHOW_ID,CHANNEL_ID,STATION_ID 和 TIME)彼此之間不是互相獨(dú)立的。DAY 列獨(dú)立于 TIME 列,但是它不獨(dú)立于所有演出清單的 SHOW_ID。
設(shè)想一條應(yīng)用了以下謂詞的 SQL 語句:
P1: SHOW_ID = ? P2: CHANNEL_ID = ? P3: STATION_ID = ? P4: TIME = ?假如存在這樣一個(gè)索引,其中的鍵包含謂詞 P1-P4 引用的所有列,或者鍵中的前四列包含所引用的列,優(yōu)化器將使用 FIRST4KEYCARD 索引統(tǒng)計(jì)信息(假如收集了索引統(tǒng)計(jì)信息的話),來檢測謂詞 P1-P4 之間的統(tǒng)計(jì)相關(guān)性。在應(yīng)用了這四個(gè)謂詞之后,優(yōu)化器將計(jì)算一個(gè)更準(zhǔn)確的基數(shù)估計(jì)值。例如,下面的任何一個(gè)索引可以用來檢測這四個(gè)謂詞間的統(tǒng)計(jì)相關(guān)性:
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)優(yōu)化器使用 IX1 的 FULLKEYCARD 和 FIRST4KEYCARD 統(tǒng)計(jì)信息來檢測所有四個(gè)謂詞的相關(guān)性。類似地,它也可以使用 IX2 和 IX3 的 FIRST4KEYCARD。
不能使用如下所示的索引:
IX4 ON SHOW_LISTINGS(CITY_ID, SHOW_ID, CHANNEL_ID, STATION_ID, TIME)由于每個(gè) keycard 統(tǒng)計(jì)信息都將包含 CITY_ID 列,因此該列上未定義本地等式謂詞。
假如不存在具有所需鍵的索引,那么可以在 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 上收集列組統(tǒng)計(jì)信息。優(yōu)化器使用這些列組統(tǒng)計(jì)信息,運(yùn)用與處理索引的 FIRST4KEYCARD 統(tǒng)計(jì)信息相同的方式檢測這四個(gè)謂詞間的統(tǒng)計(jì)相關(guān)性。
DB2 優(yōu)化器同樣也會(huì)考慮具有謂詞子集的索引或者列組統(tǒng)計(jì)信息。例如,看下面所示的索引:
IX5 ON SHOW_LISTINGS(SHOW_ID, STATION_ID, CITY_ID, CHANNEL_ID)該索引不能使用 FIRST2KEYCARD 來檢測謂詞 P1 和 P3 的統(tǒng)計(jì)相關(guān)性。盡管只是部分糾正了謂詞 P1-P4 間的統(tǒng)計(jì)相關(guān)性,但已足以答應(yīng)優(yōu)化器選擇一個(gè)優(yōu)秀的查詢執(zhí)行計(jì)劃。此外,盡管索引 IX5 中的完整鍵包含 CHANNEL_ID 列,仍然不能使用 FULLKEYCARD 統(tǒng)計(jì)信息來檢測與 P2 的相關(guān)性,因?yàn)樗?CITY_ID 列沒有在謂詞中引用。多個(gè)等式連接謂詞的統(tǒng)計(jì)相關(guān)性DB2 SQL 優(yōu)化器同樣嘗試檢測兩個(gè)表中的多個(gè)等式連接謂詞間的統(tǒng)計(jì)相關(guān)性。
示例 2:考慮示例 1 中描述的 SHOW_LISTINGS 表,另外,RATINGS 表包含如下列: 表 2. RATINGS 表的描述
列名 描述SHOW_ID 表外鍵,包含關(guān)于各演出清單的信息CHANNEL_ID 表外鍵,包含關(guān)于播放演出的每個(gè)頻道的信息STATION_ID 表外鍵,包含和頻道相關(guān)的每個(gè)電視臺(tái)的信息CITY_ID 表外鍵,包含關(guān)于上演該演出的每個(gè)城市的信息DAY 播放演出的日期TIME 播放演出的時(shí)間RATING 在一天的某個(gè)時(shí)間,在特定城市中,某個(gè)電視臺(tái)頻道的演出清單的收視率RATINGS 表包含描述不同城市演出清單的收視率信息,用戶可能需要查詢 RATINGS 表和 SHOW_LISTINGS 表的連接以檢索這兩個(gè)表的屬性。一個(gè)查詢在該連接上應(yīng)用的謂詞集包含以下內(nèi)容:
P1: SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID P2: SHOW_LISTINGS.CHANNEL_ID = RATINGS.CHANNEL_ID P3: SHOW_LISTINGS.STATION_ID = RATINGS.STATION_IDP1-P3 這三個(gè)謂詞可能不是互相獨(dú)立的;優(yōu)化器試圖使用任何可用的多列統(tǒng)計(jì)信息來檢測謂詞之間的相關(guān)性。
優(yōu)化器只能檢測和說明每一對(duì)連接表上的多個(gè)連接謂詞間的統(tǒng)計(jì)相關(guān)性。例如,假如一條 SQL 語句包含如下謂詞:
P1: T1.A = T2.A P2: T1.B = T2.B P3: T1.C = T3.C優(yōu)化器只嘗試檢測 P1 和 P2 間的統(tǒng)計(jì)相關(guān)性,因?yàn)樗鼈冎粦?yīng)用于相同的兩個(gè)表的連接,T1 和 T2。P3 應(yīng)用于 T1 和 T2 的連接;那是一個(gè)不同的連接。假如添加了第四個(gè)謂詞,例如:
P4: T1.D = T2.D優(yōu)化器將進(jìn)一步嘗試檢測 P3 和 P4 間的統(tǒng)計(jì)相關(guān)性。
為了說明等式連接謂詞間的統(tǒng)計(jì)相關(guān)性,優(yōu)化器使用連接所涉及的兩表之一的多列統(tǒng)計(jì)信息;這個(gè)表被視為連接的父表。因此只需要在連接的父表中收集列組統(tǒng)計(jì)信息。連接的另一個(gè)表被指定為子表。假如父表不能確定,那么優(yōu)化器就不能使用多列統(tǒng)計(jì)信息來檢測連接謂詞間的統(tǒng)計(jì)相關(guān)性。
附錄 B 提供了優(yōu)化器如何確定兩個(gè)連接表中的父表和子表的具體示例和描述。對(duì)連接中的父表進(jìn)行標(biāo)識(shí),或者判定連接中是否有父表,這對(duì)于避免收集無用的列組統(tǒng)計(jì)信息是非常有用的。假如尚無合適的索引可用,那么在連接中的每個(gè)表上收集列組統(tǒng)計(jì)信息即可。
收集多列統(tǒng)計(jì)信息
優(yōu)化器考慮使用所有可用的索引 keycard 統(tǒng)計(jì)信息。假如具有統(tǒng)計(jì)相關(guān)性的謂詞所引用的列集中,索引 keycard 統(tǒng)計(jì)信息不可用,可以使用 RUNSTATS 命令收集列組統(tǒng)計(jì)信息。下面是從 DB2 V82 提取的語法。
注重:對(duì)于 DB2 9,請?jiān)?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 子句答應(yīng)您指定一個(gè)列的列表,為它們收集統(tǒng)計(jì)信息。假如您指定了一組列,則會(huì)收集該組中惟一值的數(shù)量。未列出的列的統(tǒng)計(jì)信息非常明確。您可以在 “on-cols-clause 和 “on-dist-cols-clause 中使用這個(gè)子句。
注重:目前還不支持為一組列收集分布統(tǒng)計(jì)信息。
注重:假如啟用了 automatic runstats 并使用 RUNSTATS 命令收集了列組統(tǒng)計(jì)信息,automatic runstats 將覆蓋這些統(tǒng)計(jì)信息,并丟棄列組統(tǒng)計(jì)信息。 AUTO_RUNSTATS 數(shù)據(jù)庫配置設(shè)置表明是否啟用了 automatic runstats:
Automatic runstats (AUTO_RUNSTATS)=ON假如設(shè)置為 “ON,則啟用 automatic runstats。
AUTO_RUNSTATS 默認(rèn)情況下使用 “具有所有分布和示例的具體索引 的 RUNSTATS 選項(xiàng)。
您可以使用統(tǒng)計(jì)信息配置文件來覆蓋默認(rèn)的 RUNSTATS 選項(xiàng)。您可以將希望收集的任意列組統(tǒng)計(jì)信息添加到此配置文件中,以避免 automatic runstats 覆蓋它們。
“統(tǒng)計(jì)信息配置文件 提供了關(guān)于統(tǒng)計(jì)信息配置文件的具體資料。
對(duì)于數(shù)據(jù)庫分區(qū)特性(database partitioning feature,DPF)環(huán)境,automatic runstats 總是在目錄分區(qū)上收集統(tǒng)計(jì)信息。假如表不存在于這個(gè)目錄節(jié)點(diǎn)上,將使用表駐留的節(jié)點(diǎn)組的第一個(gè)分區(qū)。
將使用 RUNSTATS 命令的 “ON COLUMNS 選項(xiàng)收集列組統(tǒng)計(jì)信息。例如,使用 SHOW_LISTINGS 表收集 SHOW_LISTINGS.SHOW_ID、SHOW_LISTINGS.CHANNEL_ID 和 SHOW_LISTINGS.STATION_ID 中的列組統(tǒng)計(jì)信息,執(zhí)行如下 RUNSTATS 命令:
RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID, STATION_ID))假如只在 DAY 列收集列統(tǒng)計(jì)信息以及收集 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 列的列組統(tǒng)計(jì)信息,則執(zhí)行以下的 RUNSTATS 命令:
RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID, STATION_ID, TIME), DAY)注重:列統(tǒng)計(jì)信息是在列組中列出的所有列上收集的。在上面的命令中,列統(tǒng)計(jì)信息同樣是在每一個(gè)列中收集的(SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME)。 為了收集所有列的統(tǒng)計(jì)信息以及在 SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME 中收集列組統(tǒng)計(jì)信息,執(zhí)行下面的 RUNSTATS 命令:
RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON ALL COLUMNS AND ON COLUMNS ((SHOW_ID, CHANNEL_ID, STATION_ID, TIME))要收集多個(gè)多列統(tǒng)計(jì)信息,可以提供一個(gè)組集。下面的 RUNSTATS 命令在組(SHOW_ID、CHANNEL_ID 和 STATION_ID)和組(SHOW_ID、CHANNEL_ID、STATION_ID 和 TIME)中收集多列統(tǒng)計(jì)信息,同樣也在 DAY 列上收集了列統(tǒng)計(jì)信息:
RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID, STATION_ID), (SHOW_ID, CHANNEL_ID, STATION_ID, TIME), DAY)注重:對(duì)于索引統(tǒng)計(jì)信息來說,將為索引鍵的前兩個(gè)列、前三列和前四列收集多個(gè)多列統(tǒng)計(jì)信息,而一個(gè)列組基數(shù)統(tǒng)計(jì)信息是為指定的各列組收集的。
確定何時(shí)收集列組統(tǒng)計(jì)信息
確定何時(shí)收集列組統(tǒng)計(jì)信息以及要收集哪些列組統(tǒng)計(jì)信息是比較困難的。這一節(jié)將為您介紹一些方法,幫助您確定何時(shí)需要列組統(tǒng)計(jì)信息。
本節(jié)的示例使用了 SAMPLE 數(shù)據(jù)庫,可以通過執(zhí)行 “db2sampl 創(chuàng)建,此數(shù)據(jù)庫使用 db2level:
Informational tokens are "DB2 v8.1.1.120", "s060801", "U808888", and FixPak "13".示例 3:本地等式謂詞
創(chuàng)建了 SAMPLE 數(shù)據(jù)庫后,并沒有在表上收集統(tǒng)計(jì)信息。首先,需要在 EMPLOYEE 表中收集統(tǒng)計(jì)信息:
RUNSTATS ON TABLE SCHEMA_NAME.EMPLOYEE WITH DISTRIBUTION;考慮 SAMPLE 數(shù)據(jù)庫中 EMPLOYEE 表上的如下查詢:
SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY FROM EMPLOYEE WHERE JOB='ANALYST';該查詢從 EMPLOYEE 表返回兩條記錄:
EMPNO FIRSTNME LASTNAMEWORKDEPT SEX JOB SALARY ------ ------------ --------------- -------- --- -------- ----------- 000130 DOLORES QUINTANAC01 F ANALYST 23800.00 000140 HEATHER NICHOLLSC01 F ANALYST 28420.00 2 record(s) selected.看一下為此查詢選擇的查詢執(zhí)行計(jì)劃。
為此,使用 EXPLAIN 工具,它要求 EXPLAIN 表存在。
為了創(chuàng)建 EXPLAIN 表,執(zhí)行以下代碼:
db2 -tvf $DB2PATH/misc/EXPLAIN.DDL創(chuàng)建了 EXPLAIN 表之后,像下面這樣對(duì)查詢進(jìn)行 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 工具查看查詢執(zhí)行計(jì)劃:
db2exfmt -d <DBNAME> -1 -g -o <FILENAME>使用您喜愛的文本編輯器,您應(yīng)看到像下面這樣的查詢執(zhí)行計(jì)劃:
2 TBSCAN ( 2) 30.8464 2 | 32 TABLE: SKAPOOR EMPLOYEE基數(shù)估計(jì)值 2 符合實(shí)際結(jié)果。
為這個(gè)查詢添加幾個(gè)冗余的等式謂詞 :
SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY FROM EMPLOYEE WHERE JOB='ANALYST' AND SEX='F' AND WORKDEPT='C01';此查詢返回和上面相同的結(jié)果集。但是看一下 EXPLAIN 工具生成的查詢執(zhí)行計(jì)劃,基數(shù)估計(jì)值并不符合實(shí)際結(jié)果:
0.0761719 TBSCAN ( 2) 31.4115 2 | 32 TABLE: SKAPOOR EMPLOYEEDB2 優(yōu)化器假設(shè)這三個(gè)謂詞是彼此獨(dú)立的,因?yàn)椴淮嬖谙嚓P(guān)的索引或列組統(tǒng)計(jì)信息。
在 JOB、WORKDEPT 和 SEX 列中收集列組統(tǒng)計(jì)信息。
RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE ON ALL COLUMNS AND COLUMNS ((JOB, WORKDEPT, SEX)) WITH DISTRIBUTION;使用這三個(gè)列的列組統(tǒng)計(jì)信息,DB2 優(yōu)化器計(jì)算出一個(gè)更準(zhǔn)確的基數(shù)估計(jì)值:
1.77778 TBSCAN ( 2) 31.4214 2 | 32 TABLE: SKAPOOR EMPLOYEE與單一謂詞查詢計(jì)算出的結(jié)果不同,所計(jì)算出的基數(shù)估計(jì)值并不是 2,這是因?yàn)榱薪M統(tǒng)計(jì)信息是一個(gè)一致分布統(tǒng)計(jì)信息。
示例 4:等式連接謂詞
這個(gè)示例集中關(guān)注表 ORG 和 STAFF 的連接。首先,需要在這兩個(gè)表上收集統(tǒng)計(jì)信息。現(xiàn)在,已經(jīng)收集好了基本的統(tǒng)計(jì)信息。
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;這個(gè)查詢返回 8 個(gè)記錄:
NAME DEPTNUMB DEPTNAME SALARY --------- -------- -------------- --------- Molinare10 Head Office 22959.20 Hanes 15 New England 20659.80 Sanders 20 Mid Atlantic18357.50 Marenghi38 South Atlantic 17506.75 Plotz 42 Great Lakes 18352.80 Fraye 51 Plains 21150.00 Lea 66 Pacific 18555.50 Quill 84 Mountain19818.00 8 record(s) selected.使用 EXPLAIN 工具查看查詢執(zhí)行計(jì)劃:
1 TBSCAN ( 2) 33.2225 2 | 1 SORT ( 3) 33.151 2 | 1 HSJOIN ( 4) 33.0248 2 /-----+----- 358 TBSCAN TBSCAN ( 5) ( 6) 17.2334 15.3736 11 || 358 TABLE: SKAPOOR TABLE: SKAPOOR STAFF ORG這個(gè)示例使用了收集列組統(tǒng)計(jì)信息的簡單方法。附錄 B 包含一些示例,對(duì)判定連接中的父表做了進(jìn)一步的分析。
對(duì) STAFF 表的 ID、DEPT 列和 ORG 表的 MANAGER、DEPTNUMB 列做了連接,所以要在這兩組列中收集列組統(tǒng)計(jì)信息:
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 優(yōu)化器使用收集到的列組統(tǒng)計(jì)信息正確地估計(jì)了基數(shù):
8 TBSCAN ( 2) 33.5658 2 | 8 SORT ( 3) 33.4243 2 | 8 HSJOIN ( 4) 33.0363 2 /-----+----- 358 TBSCAN TBSCAN ( 5) ( 6) 17.2334 15.3736 11 || 358 TABLE: SKAPOOR TABLE: SKAPOOR STAFF ORG示例 5:查看多列統(tǒng)計(jì)信息
優(yōu)化器利用兩種類型的多列統(tǒng)計(jì)信息:索引 keycard 統(tǒng)計(jì)信息和列組統(tǒng)計(jì)信息。這個(gè)示例提供了查看表中可用多列統(tǒng)計(jì)信息的步驟。
選項(xiàng) 1. 使用 db2look 工具
db2look 工具用來生成 DDL 語句,從而重新創(chuàng)建數(shù)據(jù)庫中定義的對(duì)象。可以使用 -m 選項(xiàng)來顯示為這些對(duì)象收集的統(tǒng)計(jì)信息。
在 ORG 表中收集列組統(tǒng)計(jì)信息和索引統(tǒng)計(jì)信息:
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 表的統(tǒng)計(jì)信息:
db2look -d sample -e -a -m -t ORG -o org.ddl注重:使用 -h 選項(xiàng)查看關(guān)于 DB2look 工具的信息。
在 org.ddl 文件中查看輸出。它應(yīng)該包含如下用于列組統(tǒng)計(jì)信息的 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 中,列組統(tǒng)計(jì)信息添加到了 db2look 工具中。
上面的 update 語句列出了 SYSCAT.COLGROUPCOLS 視圖的所有列,以及來自 SYSSTAT.COLGROUPS 的相關(guān)多列統(tǒng)計(jì)信息,它表示列集中不同組的數(shù)量。在這個(gè)示例中,以上的語句描述了列集(DEPTNUMB、DEPTNAME、MANAGER、DIVISION 和 LOCATION)具有八個(gè)不同的組。
org.ddl 文件也包含如下用于索引統(tǒng)計(jì)信息的語句:
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 語句描述了下列多列統(tǒng)計(jì)信息。FIRST2KEYCARD 統(tǒng)計(jì)信息描述了列(DEPTNUMB,DEPTNAME)中不同組的數(shù)量,F(xiàn)IRST3KEYCARD 和 FULLKEYCARD 描述了完整列集(DEPTNUMB,DEPTNAME,MANAGER)中不同組的數(shù)量。FIRST4KEYCARD 的值為 -1,這是因?yàn)樗饕谠撴I中只有 3 列。
選項(xiàng) 2. 查詢目錄表
可以從 DB2 目錄表中查詢與 DB2look 工具輸出中所描述的相同的信息。
假如尚未創(chuàng)建索引,請按選項(xiàng) 1 中的步驟 1 創(chuàng)建索引,在多個(gè)表中收集多個(gè)列組統(tǒng)計(jì)信息:
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));查詢目錄表來檢索列組統(tǒng)計(jì)信息。注重下面的查詢是一個(gè)遞歸 SQL 語句,它會(huì)導(dǎo)致一個(gè)可以忽略的 SQL0347W 警告。可以使用 “UPDATE COMMAND OPTIONS USING W OFF 選項(xiàng)阻止該警告出現(xiàn)。
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 結(jié)果列并強(qiáng)制轉(zhuǎn)換為 CHAR(128),假如結(jié)果超過 128 個(gè)字符,它會(huì)將結(jié)果截?cái)唷T谶@個(gè)例子中,可能需要將 CAST 修改為一個(gè)更大的字符串。
TABSCHEMA TABNAMECOLS COLGROUPCARD ---------- ---------- -----------------------------//------ ----------------- SKAPOOREMPLOYEE EMPNO,WORKDEPT32 SKAPOOREMPLOYEE EMPNO,WORKDEPT,JOB32 SKAPOORORGDEPTNUMB,DEPTNAME 8 SKAPOORORGMANAGER,DIVISION 8 SKAPOORORGDEPTNUMB,DEPTNAME,MANAGER,DIVISION,LOCATION8 5 record(s) selected with 1 warning messages suppressed.這些記錄描述了 EMPLOYEE 表的兩列組統(tǒng)計(jì)信息和 ORG 表的三列組統(tǒng)計(jì)信息。
注重:在上面的查詢中,注重 SYSCAT.SYSCOLGROUPCOLS 視圖中的名為 “ORIDNAL 的列。在 DB2 9 中,其拼寫改為了 “ORDINAL,所以,這個(gè)查詢需要按照在 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 ;查詢目錄表以檢索索引統(tǒng)計(jì)信息。
注重:在 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 統(tǒng)計(jì)信息描述了在列(DEPTNUMB 和 DEPTNAME)中不同組的數(shù)量,F(xiàn)IRST3KEYCARD 和 FULLKEYCARD 描述了完整列集(DEPTNUMB,DEPTNAME 和 MANAGER)中不同組的數(shù)量。FIRST4KEYCARD 值為 -1,這是因?yàn)樗饕阪I中只包含三列。
練習(xí)在示例 3 和 4 中,優(yōu)化器使用了索引統(tǒng)計(jì)信息,而沒有使用列組統(tǒng)計(jì)信息,通過說明統(tǒng)計(jì)信息相關(guān)性來修正基數(shù)估計(jì)值。
嘗試以下步驟:
創(chuàng)建如下索引:
IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX); IXSTAFF_1 ON STAFF(ID, DEPT); IXORG_1 ON ORG(MANAGER, DEPTNUMB);對(duì)這些索引收集統(tǒng)計(jì)信息,但不收集任何列組統(tǒng)計(jì)信息:
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;對(duì)示例 3 和 4 中的查詢進(jìn)行 EXPLAIN 處理。所得到的基數(shù)估計(jì)值符合上面的查詢執(zhí)行計(jì)劃;然而,由于可用索引的不同,實(shí)際的計(jì)劃會(huì)有所不同。注重收集的 DETAILED 統(tǒng)計(jì)信息并不影響基數(shù)估計(jì)值。丟棄步驟 1 中創(chuàng)建的 IXEMP_1 和 IXSTAFF_1 索引,創(chuàng)建兩個(gè)新的索引:
IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX, EMPNO); IXSTAFF_1 ON STAFF(ID, DEPT,NAME,JOB);重復(fù)步驟 2 和步驟 3。其最后的基數(shù)估計(jì)值是相同的。
附錄 A. 自動(dòng)統(tǒng)計(jì)信息分析
RUNSTATS 實(shí)用程序提供了一個(gè)選項(xiàng),用它可以注冊和使用一個(gè)統(tǒng)計(jì)信息配置文件。DB2 的自動(dòng)統(tǒng)計(jì)信息分析特性可以自動(dòng)地生成統(tǒng)計(jì)信息配置文件。啟用了這個(gè)特性后,將會(huì)收集有關(guān)數(shù)據(jù)庫活動(dòng)的信息并將其存儲(chǔ)在查詢反饋倉庫中。在這些數(shù)據(jù)的基礎(chǔ)之上,生成一個(gè)統(tǒng)計(jì)信息配置文件。該特性還會(huì)推薦對(duì)本地等式謂詞使用兩列組統(tǒng)計(jì)信息。這在測試環(huán)境中是一種游泳的工具,可標(biāo)識(shí)有用的列組統(tǒng)計(jì)信息。
Info Center 中包含關(guān)于使用 自動(dòng)統(tǒng)計(jì)信息分析 的更具體信息。
.注重:統(tǒng)計(jì)信息配置文件的自動(dòng)生成只在 DB2 串行模式中是激活的,在聯(lián)邦查詢、DPF 環(huán)境之中以及使用分區(qū)內(nèi)并行性時(shí),該特性是被禁止的。
附錄 B. 確定兩個(gè)連接表中的父表
多個(gè)等式謂詞的統(tǒng)計(jì)相關(guān)性 一節(jié)中討論了一種簡單方法,通過說明等式連接謂詞間的統(tǒng)計(jì)相關(guān)性而收集多列統(tǒng)計(jì)信息,這一節(jié)將介紹優(yōu)化器如何確定兩個(gè)連接表中的父表(假如有的話)。鑒別優(yōu)化器是否會(huì)檢測一個(gè)父表,假如會(huì)的話,哪一個(gè)是父表,這對(duì)于了解何時(shí)進(jìn)行列組統(tǒng)計(jì)信息的收集才是有效的以及在哪個(gè)表上收集是非常有用的。
優(yōu)化器在一組連接兩表的謂詞中標(biāo)識(shí)父表,這個(gè)表至少是一個(gè)連接謂詞的父表,而且不是任何其他連接謂詞的子表。一個(gè)連接謂詞的父表被確定為在謂詞列中具有較多不同值的表。例如,在 SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID 連接謂詞中,假如 SHOW_LISTINGS.SHOW_ID 的 COLCARD 統(tǒng)計(jì)信息比 RATINGS.SHOW_ID 的 COLCARD 統(tǒng)計(jì)信息多,那么 SHOW_LISTINGS 就是這個(gè)連接謂詞的父表,RATINGS 則是子表。
此外,優(yōu)化器還嘗試使用范圍統(tǒng)計(jì)信息(HIGH2KEY 和 LOW2KEY)來驗(yàn)證父表,方法是確保子表中的值集是父表的子集。例如,在連接謂詞 SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID 中,假如符合以下條件:
SHOW_LISTINGS.SHOW_ID 的 COLCARD 統(tǒng)計(jì)信息多于 RATINGS.SHOW_ID 的統(tǒng)計(jì)信息,并且
SHOW_LISTINGS.SHOW_ID 的 HIGH2KEY 多于或等于 RATINGS.SHOW_ID 的 HIGH2KEY,并且
RATINGS.SHOW_ID 的 LOW2KEY 少于或等于 RATINGS.SHOW_ID 的 LOW2KEY
那么 SHOW_LISTINGS 是這個(gè)連接謂詞的父表,而 RATINGS 則是子表。
示例 B.1
假設(shè)以下一組謂詞:
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 中,假設(shè) COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。
在 P2 中,假設(shè) COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID)。
在 P3 中,假設(shè) COLCARD(SHOW_LISTINGS.STATION_ID) > COLCARD(RATINGS.STATION_ID)。優(yōu)化器將 SHOW_LISTINGS 表標(biāo)識(shí)為所有三個(gè)謂詞的父表,所以它同樣將 SHOW_LISTINGS 標(biāo)識(shí)為連接的父表。因此優(yōu)化器使用 SHOW_LISTINGS 表中的列(SHOW_ID,CHANNEL_ID 和 STATION_ID)上可用的多列統(tǒng)計(jì)信息。
示例 B.2
使用示例 B.1 中的謂詞:
在 P1 中,假設(shè) COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。
在 P2 中,假設(shè) COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID)。
在 P3 中,假設(shè) COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID)。
優(yōu)化器在謂詞 P1 和 P2 中將 SHOW_LISTINGS 表標(biāo)識(shí)為父表,在謂詞 P3 中既不是子表,也不是父表。所以優(yōu)化器也將 SHOW_LISTINGS 標(biāo)識(shí)為連接的父表。因此,優(yōu)化器使用 SHOW_LISTINGS 表中的列(SHOW_ID,CHANNEL_ID 和 STATION_ID)上可用的多列統(tǒng)計(jì)信息。
示例 B.3
使用示例 B.1 中的謂詞:
在 P1 中,假設(shè) COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID)。
在 P2 中,假設(shè) COLCARD(SHOW_LISTINGS.CHANNEL _ID) < COLCARD(RATINGS.CHANNEL_ID)。在 P3 中,假設(shè) COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID)。
優(yōu)化器在謂詞 P1 中將 SHOW_LISTINGS 表標(biāo)識(shí)為父表,在謂詞 P2 中將其標(biāo)識(shí)為子表,在謂詞 P3 中既不是子表也不是父表。所以,并不將 SHOW_LISTINGS 標(biāo)識(shí)為連接中的父表(也不將 RATINGS 標(biāo)識(shí)為連接的父表)。因此,優(yōu)化器并不會(huì)檢測這三個(gè)連接的謂詞間的統(tǒng)計(jì)相關(guān)性。
數(shù)據(jù)庫分區(qū)特性
在一個(gè) DPF 環(huán)境中,假如表跨多個(gè)數(shù)據(jù)庫分區(qū)而被分區(qū),在下列條件滿足的情況下,只能使用范圍統(tǒng)計(jì)信息:
兩個(gè)表在相同的列中被分區(qū)
表是并置的,就是說,它們處于同一節(jié)點(diǎn)組
連接謂詞引用所有的分區(qū)鍵列
在相同的節(jié)點(diǎn)收集統(tǒng)計(jì)信息
假如不能夠使用范圍統(tǒng)計(jì)信息,那么優(yōu)化器只能使用 COLCARD 統(tǒng)計(jì)信息來確定連接中的父表。在 DPF 環(huán)境中,在單個(gè)節(jié)點(diǎn)中收集統(tǒng)計(jì)信息將會(huì)導(dǎo)致在 COLCARD 統(tǒng)計(jì)信息出現(xiàn)錯(cuò)誤。因此,確定父表時(shí),優(yōu)化器答應(yīng) COLCARD 統(tǒng)計(jì)信息中存在一些偏差(1%)。然而,這種偏差是以多列統(tǒng)計(jì)信息為基礎(chǔ)的,因此假如該連接不是中立 的,并且連接中沒有很明顯的父表,那么在 DPF 中應(yīng)該使用收集列組統(tǒng)計(jì)信息的簡單方法。
示例 B.4
1. 確定兩個(gè)表是否在相同列上被分區(qū)
除非兩個(gè)表的數(shù)據(jù)分布相同,否則不能使用范圍統(tǒng)計(jì)信息(HIGH2KEY 和 LOW2KEY)。因此,假如表不是在相同列被分區(qū),優(yōu)化器將無法推斷出數(shù)據(jù)在兩個(gè)表中的分布相同。
假設(shè)有兩個(gè)表,T1 和 T2。T1 在多個(gè)數(shù)據(jù)庫分區(qū)中被分區(qū),在列(C1 和 C2)中具有分區(qū)鍵。同樣,T2 也進(jìn)行了分區(qū),其分區(qū)鍵在列(C2 和 C3)中。
例 1.1 使用下列謂詞連接 T1 和 T2:
P1: T1.C1=T2.C2 P2: T1.C2=T2.C3這兩個(gè)表被認(rèn)為是在相同的列進(jìn)行了分區(qū),因?yàn)檫B接謂詞按照與其各自的分區(qū)鍵相同的次序應(yīng)用于列中。
例 1.2 使用下列謂詞:
P1: T1.C1=T2.C3 P2: T1.C2=T2.C2謂詞沒有按照與其各自的分區(qū)鍵相同的次序應(yīng)用于列中,所以這兩個(gè)表被認(rèn)為不是在相同列上分區(qū)的。
例 1.3 使用下列謂詞:
P1: T1.C1=T2.C1 P2: T1.C2=T2.C2 P3: T1.C3=T2.C3這些表被認(rèn)為不是在相同列分區(qū)的。
例 1.4 來看一下和示例 1.3 使用相同謂詞的情形,但是假設(shè) T2 是在列(C1,C2 和 C3)中分區(qū)的。
盡管表 T1 是在相同列分區(qū)的(T2 分區(qū)鍵的兩個(gè)主要列),由于 T2 在 C3 中進(jìn)一步分區(qū),與只在(C1 和 C2)中分區(qū)相比,這將導(dǎo)致數(shù)據(jù)分布不同。因此,這兩個(gè)表被認(rèn)為是在不同列進(jìn)行分區(qū)的。
2. 確定這兩個(gè)表是否是并置的
假設(shè)有兩個(gè)表,T1 和 T2,T1 屬于節(jié)點(diǎn)組 N0 而 T2 屬于節(jié)點(diǎn)組 N1,其中 N0 包含分區(qū)數(shù) 0 和 1 ,N1 包含分區(qū)數(shù) 1 和 2 。由于這兩個(gè)表不在同一個(gè)節(jié)點(diǎn)組,將認(rèn)為它們不是并置的。
3. 確定連接的謂詞是否引用所有的分區(qū)鍵列
假設(shè)有兩個(gè)表,T1 和 T2。T1 在多個(gè)數(shù)據(jù)庫分區(qū)中被分區(qū),分區(qū)鍵在列(C1 和 C2)。同樣,T2 也被分區(qū),分區(qū)鍵在列(C2 和 C3)。3.1 使用這些謂詞來連接 T1 和 T2:
P1: T1.C1=T2.C2 P2: T1.C2=T2.C3這兩個(gè)謂詞都包含了所有的分區(qū)鍵列。
例 3.2 假如在示例 3.1 謂詞中添加第三個(gè)謂詞 P3,T1.C3=T2.C1,那么這三個(gè)謂詞合起來仍然包含兩個(gè)表中的所有分區(qū)鍵列。然而,假如僅使用 P1 和 P3,所有這三個(gè)謂詞并不包含分區(qū)鍵列。
例 3.3假如在示例 3.1 謂詞中添加第三個(gè)謂詞 P3,T1.C3=T2.C3,那么這三個(gè)謂詞合起來仍然包含兩個(gè)表中的所有分區(qū)鍵列。然而,假如只使用P1 和 P3,那么只包含了 T2 的分區(qū)鍵列而沒有包含 T1 的,所以條件并不符合。
完全限定的惟一索引
假如在上述條件的基礎(chǔ)上,沒有一個(gè)表被指定為連接的父表,優(yōu)化器將進(jìn)一步檢查一個(gè)完全限定的惟一索引。假如連接謂詞完全限定一個(gè)惟一索引,優(yōu)化器使用惟一索引的 FULLKEYCARD 統(tǒng)計(jì)信息來檢測和說明相等連接謂詞之間的統(tǒng)計(jì)相關(guān)性。
中立連接
假如未在兩個(gè)表間的任一等式連接謂詞中標(biāo)識(shí)出父表,優(yōu)化器將把這個(gè)連接標(biāo)識(shí)為中立(neutral)。假如兩個(gè)列的 COLCARD 相同,并且它們包含的值的范圍也是相同的(HIGH2KEY 和 LOW2KEY 統(tǒng)計(jì)信息是等同的),則不對(duì)這個(gè)等式連接謂詞標(biāo)識(shí)父表。
在 DB2 V8 的 FixPaks 13 及更早版本中,假如是一個(gè)中立的 NPK 連接,優(yōu)化器就不會(huì)為兩個(gè)表的連接說明一組等式連接謂詞間的統(tǒng)計(jì)相關(guān)性。在 V8 FixPak 14 和 DB2 9 中,優(yōu)化器的統(tǒng)計(jì)相關(guān)性檢測得到了擴(kuò)展,可以對(duì)中立的 NPK 連接進(jìn)行統(tǒng)計(jì)相關(guān)性說明。
兩個(gè)表引用相同的基表,這種自連接是中立連接的特例。在 V8.2 中,優(yōu)化器開始為這種特例說明統(tǒng)計(jì)相關(guān)性。
示例 B.5:在父表中收集列組統(tǒng)計(jì)信息
這個(gè)例子主要關(guān)注表 ORG 和 STAFF 間的連接。首先,需要為表收集統(tǒng)計(jì)信息。現(xiàn)在,已經(jīng)收集了基本的統(tǒng)計(jì)信息:
RUNSTATS ON TABLE <SCHEMA_NAME>.ORG; RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF;假設(shè)如下查詢連接表 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;這個(gè)查詢返回 8 個(gè)記錄:
NAME DEPTNUMB DEPTNAME SALARY --------- -------- -------------- --------- Molinare10 Head Office 22959.20 Hanes 15 New England 20659.80 Sanders 20 Mid Atlantic18357.50 Marenghi38 South Atlantic 17506.75 Plotz 42 Great Lakes 18352.80 Fraye 51 Plains 21150.00 Lea 66 Pacific 18555.50 Quill 84 Mountain19818.00 8 record(s) selected.1. 使用 EXPLAIN 工具,查看查詢執(zhí)行計(jì)劃:
1 TBSCAN ( 2) 33.2225 2 | 1 SORT ( 3) 33.151 2 | 1 HSJOIN ( 4) 33.0248 2 /-----+----- 358 TBSCAN TBSCAN ( 5) ( 6) 17.2334 15.3736 11 || 358 TABLE: SKAPOOR TABLE: SKAPOOR STAFF ORG2. 查看連接謂詞引用的列的列統(tǒng)計(jì)信息。如下查詢?yōu)閮蓚€(gè)連接謂詞中引用的表 ORG 和 STAFF 中的列從 DB2 目錄表中檢索有趣的列統(tǒng)計(jì)信息:
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 列統(tǒng)計(jì)信息
COLNAME COLCARD HIGH2KEY LOW2KEYDEPTNUMB 8 66 15MANAGER 8 270 30DEPT 8 66 15ID 35 340 203. 計(jì)算基數(shù)估計(jì)值。等式連接謂詞的過濾因子的估計(jì)值計(jì)算如下:
1/max(colcard_LHS,colcard_RHS).其中 LHS 在連接謂詞的左邊,RHS 在連接謂詞的右邊。本例中有以下兩個(gè)連接謂詞:
P1: org.manager=staff.id P2: org.deptnumb=staff.dept以及過濾因子(ff),P1 和 P2 計(jì)算如下:
ff(P1) = 1 / max (8,35) = 1/35 = 0.0285714 ff(P2) = 1/max(8,8) = 1/8 = 0.125使用過濾因子以及兩個(gè)表的基數(shù)估計(jì)值,連接基數(shù)計(jì)算如下:
JoinCard = Cardinality(ORG) * cardinality(STAFF) * ff(P1) * ff(P2) = 35 * 8 * 0.0285714 * 0.125 = 14. 在連接中標(biāo)識(shí)父表。
在表 B.5 中,列統(tǒng)計(jì)信息顯示 STAFF 是連接的父表,因?yàn)榉弦韵聴l件:
對(duì)于謂詞 org.manager=staff.id:
colcard(MANAGER) < colcard(ID) high2key(MANAGER) < high2key(ID) low2key(MANAGER) > low2key(ID)因此,這個(gè)謂詞的父表是 STAFF。
對(duì)于謂詞 org.deptnumb=staff.dept,colcard、high2key 和 low2key 統(tǒng)計(jì)信息是等同的。因此,這個(gè)謂詞不存在父表,它應(yīng)被視為“中立。
5. 在父表中收集列組統(tǒng)計(jì)信息。
在步驟 4 中,STAFF 被標(biāo)識(shí)為連接的父表,ORG 被標(biāo)識(shí)為連接的子表,所以應(yīng)在 STAFF 表的列(ID,DEPT)中收集列組統(tǒng)計(jì)信息:
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF ON ALL COLUMNS AND COLUMNS ((ID,DEPT));使用這兩個(gè)列的列組統(tǒng)計(jì)信息,DB2 優(yōu)化器就可以準(zhǔn)確地估計(jì)出基數(shù):
8 TBSCAN ( 2) 33.5658 2 | 8 SORT ( 3) 33.4243 2 | 8 HSJOIN ( 4) 33.0363 2 /-----+----- 358 TBSCAN TBSCAN ( 5) ( 6) 17.2334 15.3736 11 || 358 TABLE: SKAPOOR TABLE: SKAPOOR STAFF ORG示例 B.6 中立連接
考慮 T1 和 T2 這兩個(gè)表的連接,使用以下謂詞:
P1: T1.C1 = T2.C1 P2: T1.C2 = T2.C2 P3: T1.C3 = T2.C3假設(shè)這兩個(gè)表具有以下的統(tǒng)計(jì)信息:表 B.6 中立連接統(tǒng)計(jì)信息
TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEYT1 C1 100 99 2 T2 C1 100 99 2T1 C2 10 1999 1900 T2 C2 10 1999 1900T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'所有的謂詞被看作是中立的,這是由于兩個(gè)表的 stats 是相等的。因此,在 V8 FixPak 14 和 DB2 9 中,應(yīng)該在任一個(gè)表(不要求兩個(gè)表)的列(C1、C2 和 C3)中收集列組統(tǒng)計(jì)信息,這樣,優(yōu)化器就可以檢測這些連接謂詞的統(tǒng)計(jì)相關(guān)性。
示例 B.7
使用和示例 B.6 相同的謂詞,假設(shè)表具有如下統(tǒng)計(jì)信息:表 B.7 確定父表
TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEYT1 C1 100 99 2 T2 C1 10 99 2T1 C2 10 1999 1900 T2 C2 10 1999 1900T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'在這個(gè)場景中,謂詞 P2 和 P3 看作是中立的,這是由于兩個(gè)表的列 C2 和 C3 的統(tǒng)計(jì)信息是等同的。然而,C1 的統(tǒng)計(jì)信息顯示 T1 是 P1 的父表,這是因?yàn)?T1.C1 的 COLCARD 比 T2.C1 的 COLCARD 大,并且兩個(gè)列具有等同的 HIGH2KEY 和 LOW2KEYare 統(tǒng)計(jì)信息。因此,應(yīng)該在 T1 的列(C1、C2 和 C3)中收集列組統(tǒng)計(jì)信息,這樣,優(yōu)化器就可以檢測連接謂詞間的統(tǒng)計(jì)相關(guān)性。
示例 B.8
使用和示例 B.6 相同的謂詞,假設(shè)表具有下列統(tǒng)計(jì)信息:表 B.8 統(tǒng)計(jì)信息
TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEYT1 C1 100 99 2 T2 C1 10 999 2T1 C2 10 1999 1900 T2 C2 10 1999 1900T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'在這個(gè)場景中,謂詞 P2 和 P3 被表示為中立的,這是由于兩個(gè)表的 C2 和 C3 列的統(tǒng)計(jì)信息是等同的。然而,C1 的統(tǒng)計(jì)信息表明 T1 和 T2 都不是父表,它也不是中立的,因?yàn)?T1.C1 具有一個(gè)更高的 COLCARD 統(tǒng)計(jì)信息,而 T2.C1 具有一個(gè)更高的統(tǒng)計(jì)信息。因此,應(yīng)該在 T1 或 T2 的列(C2 和 C3)中收集列組統(tǒng)計(jì)信息,這樣優(yōu)化器就可以檢測連接謂詞 P2 和 P3 之間的統(tǒng)計(jì)相關(guān)性。
示例 B.9 使用 DPF 和范圍統(tǒng)計(jì)信息
考慮 T1 和 T2 這兩個(gè)表的連接,它們在多個(gè)數(shù)據(jù)庫分區(qū)上被分區(qū),并且是并置的,統(tǒng)計(jì)信息是在相同的節(jié)點(diǎn)手機(jī)的,分區(qū)鍵在列(C1 和 C2)上,使用如下謂詞進(jìn)行連接:
P1: T1.C1 = T2.C1 P2: T1.C2 = T2.C2 P3: T1.C3 = T2.C3假設(shè)這兩個(gè)表具有如下統(tǒng)計(jì)信息:表 B.9
TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEYT1 C1 100 99 2 T2 C1 10 999 2T1 C2 10 1999 1900 T2 C2 10 1999 1900T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'這個(gè)連接限定 DPF 條件,所以優(yōu)化器可以使用范圍統(tǒng)計(jì)信息來標(biāo)識(shí)父表。在這個(gè)場景中,謂詞 P2 和 P3 被表示為中立,這是由于兩個(gè)表的 C2 和 C3 列的統(tǒng)計(jì)信息是等同的。然而,C1 的統(tǒng)計(jì)信息表明 T1 和 T2 都不是父表,也不把它看作是中立的,這是因?yàn)?T1.C1 具有一個(gè)更高的 COLCARD,而 T2.C1 具有一個(gè)更高的 HIGH2KEY 統(tǒng)計(jì)信息。因此,應(yīng)該在 T1 或 T2 的列(C2 和 C3)上收集列組統(tǒng)計(jì)信息,這樣優(yōu)化器就可以檢測連接謂詞 P2 和 P3 間的統(tǒng)計(jì)相關(guān)性。
示例 B.10 無法使用 DPF 和范圍統(tǒng)計(jì)信息
假設(shè)與 B.9 相同的場景,但是 T1 的分區(qū)鍵是在列(C1 和 C2)中,T2 的分區(qū)鍵在列(C2 和 C1)中。這個(gè)連接不滿足第一個(gè) DPF 條件,因?yàn)檫@兩個(gè)表被認(rèn)為不是在相同的列分區(qū)的;連接謂詞 T1.C1=T2.C1 在 T1 的分區(qū)鍵中引用了第一個(gè)列,但在 T2 分區(qū)鍵中引用了第二個(gè)列。因此,優(yōu)化器不能使用范圍統(tǒng)計(jì)信息來標(biāo)識(shí)父表,而只能使用 COLCARD 統(tǒng)計(jì)信息來確定父表。只在 COLCARD 的基礎(chǔ)上,連接被認(rèn)為是中立的。
示例 B.10.1 無法使用 DPF 和范圍統(tǒng)計(jì)信息
假設(shè)與 B.10 相同的場景,但具有下列統(tǒng)計(jì)信息:表 B.10
TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEYT1 C1 100 99 2 T2 C1 98 999 2T1 C2 10 1999 1900 T2 C2 11 1999 1900T1 C3 5 'Y' 'B' T2 C3 5 'Y' 'B'在 COLCARD 統(tǒng)計(jì)信息基礎(chǔ)上,T1 是謂詞 P1 的父表,而 T2 是謂詞 P2 的父表。由于 COLCARD 統(tǒng)計(jì)信息被關(guān)閉,因此多列統(tǒng)計(jì)信息的偏差將降至 1% 以內(nèi),這是優(yōu)化器在 DPF 環(huán)境中的容錯(cuò)值。在這里它可以使用簡單方法,并且應(yīng)在兩個(gè)表的所有三個(gè)列中收集列組統(tǒng)計(jì)信息。之后,假如優(yōu)化器沒有計(jì)算出一個(gè)不同的基數(shù)估計(jì)值,那么說明并未達(dá)到 1% 的偏差。
附錄 C. 有關(guān)本地謂詞的更多具體資料
多列統(tǒng)計(jì)信息(索引和列組)只提供了一組列中不同組數(shù)量的信息。因此,說明統(tǒng)計(jì)相關(guān)性時(shí),優(yōu)化器假設(shè)數(shù)據(jù)是一致分布的。然而,本地等式謂詞的選擇性估計(jì)值則使用分布統(tǒng)計(jì)信息(假如可用)來計(jì)算,從而說明數(shù)據(jù)中的偏差。由于假設(shè)數(shù)據(jù)是一致的,而實(shí)際上數(shù)據(jù)是有偏差的,為避免高估本地等式謂詞的組合選擇性估計(jì)值,F(xiàn)ixPak 10 中將對(duì)優(yōu)化器的統(tǒng)計(jì)相關(guān)性檢測做進(jìn)一步改善。
相關(guān)文章:
1. DB2 XML 全文搜索之為文本搜索做準(zhǔn)備2. Db2數(shù)據(jù)庫中常見的堵塞問題分析與處理方法3. DB2數(shù)據(jù)庫物化視圖:MQT物化查詢表的使用4. 使用DB2look重新創(chuàng)建優(yōu)化器訪問計(jì)劃(5)5. 分析DB2活動(dòng)日志滿的原因及解決DB2日志滿方法與避免方案6. 在DB2數(shù)據(jù)庫的表中插入和刪除數(shù)據(jù)7. DB2數(shù)據(jù)庫部分日常實(shí)用操作8. 講解主機(jī)DB2 9存儲(chǔ)過程的規(guī)劃和實(shí)施技巧9. 提高商業(yè)智能環(huán)境中DB2查詢的性能(2)10. DB2 9(Viper)快速入門
