|
生成 db2exfmt 輸出:
db2exfmt -d DUMMYDB -g TIC -w -1 -n % -s % -# 0 -o test_dummydb_exfmt.txt
檢查 test_dummydb_exfmt.txt 的內(nèi)容并查看訪問(wèn)計(jì)劃:
Access Plan: ----------- Total Cost: 25.8843 Query Degree: 1
Rows RETURN ( 1) Cost I/O | 4 MSJOIN ( 2) 25.8843 2 /-----+-----\ 1 4 TBSCAN TBSCAN ( 3) ( 5) 12.913 12.9682 1 1 | | 8 35 TABLE: SKAPOOR TABLE: SKAPOOR ORG STAFF
您在測(cè)試中獲得了一個(gè)不同于生產(chǎn)中的訪問(wèn)計(jì)劃。本例中,顯然我們?cè)跍y(cè)試系統(tǒng)上已經(jīng)將 DFT_QUERYOPT(默認(rèn)的查詢(xún)優(yōu)化)從 5 修改為 3。因此,您看到的是 Merge Join 計(jì)劃,而非 Hash Join 計(jì)劃,以及有一點(diǎn)點(diǎn)區(qū)別的總成本(Total Cost)。 因?yàn)檫@些計(jì)劃不匹配(假設(shè)您不確定為什么),所以要檢查 db2exfmt 輸出中的配置。見(jiàn) 表 2。 正如您可以看到的,測(cè)試(TEST)和生產(chǎn)(PRODUCTION)之間的惟一區(qū)別就是優(yōu)化級(jí)別(Optimization Level),我們特意將之從 5 修改為 3,只是為了顯示在測(cè)試環(huán)境中復(fù)制生產(chǎn)訪問(wèn)計(jì)劃為何會(huì)不成功。 本例中,您將使用下列 UPDATE 語(yǔ)句將 DFT_QUERYOPT 更新為 5:
UPDATE DB CFG FOR SAMPLE USING dft_queryopt 5
然后,停止并重新連接數(shù)據(jù)庫(kù)。再次對(duì) DUMMYDB 發(fā)出 query.sql,并使用 db2exfmt 命令生成訪問(wèn)計(jì)劃。這次,您將看到相同的訪問(wèn)計(jì)劃。否則,就進(jìn)一步確保本文中所討論的所有優(yōu)化器相關(guān)的參數(shù)都是相同的。 示例 2: 該示例顯示了 db2look 命令中 -m 選項(xiàng)的重要性。前面用 -m 選項(xiàng)收集的統(tǒng)計(jì)數(shù)據(jù)在測(cè)試和生產(chǎn)中應(yīng)該相同。本例中,我們將看到?jīng)]有正確更新統(tǒng)計(jì)數(shù)據(jù)時(shí)計(jì)劃是如何變化的。 數(shù)據(jù)庫(kù)管理器配置、數(shù)據(jù)庫(kù)配置和 db2set 注冊(cè)表變量與上面 示例 1 中的相同。這里的模式名是 SKAPOOR。用您的表的模式替換它。數(shù)據(jù)庫(kù)是相同的,與 示例 1 中一樣是 SAMPLE 和 DUMMY。這里所使用的平臺(tái)和 db2level 是 AIX 5.1 和 DB2 UDB ESE V8.2,F(xiàn)ix pack 8,單分區(qū)。 在 sample 數(shù)據(jù)庫(kù)上執(zhí)行下列命令:
db2 "connect to sample" db2 "create index name_ind on staff (name,id)" db2 "runstats on table skapoor.staff with distribution and indexes all" db2 "set current explain mode explain" db2 "select name from staff where id=10 order by name" db2 "set current explain mode no" db2 "terminate"
使用 db2exfmt 生成訪問(wèn)計(jì)劃。您將看到下面的訪問(wèn)計(jì)劃:
Access Plan: ----------- Total Cost: 0.111065 Query Degree: 1
Rows RETURN ( 1) Cost I/O | 1 IXSCAN ( 2) 0.111065 0 | 35 INDEX: SKAPOOR NAME_IND
從 sample 數(shù)據(jù)庫(kù)中收集 db2look 信息:
db2look -d sample -l -o storage.out db2look -d sample -e -a -m -t STAFF -o db2look.out db2look -d sample -f -fd -o config.out
修改這些文件以使您連接 dummy 數(shù)據(jù)庫(kù),而非之前在上面 示例 1 中所連接的 sample 數(shù)據(jù)庫(kù)。 手工修改統(tǒng)計(jì)數(shù)據(jù)之一。在 db2look.out 文件中搜索下列語(yǔ)句(請(qǐng)注意,模式名、TABSCHEMA 和 INDSCHEMA 可能與您的具體情況不同):
UPDATE SYSSTAT.INDEXES SET NLEAF=1, NLEVELS=1, FIRSTKEYCARD=35, FIRST2KEYCARD=35, FIRST3KEYCARD=-1, FIRST4KEYCARD=-1, FULLKEYCARD=35, 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=35, NUMRIDS_DELETED=0, NUM_EMPTY_LEAFS=0 WHERE INDNAME = ’NAME_IND’ AND INDSCHEMA = ’SKAPOOR ’ AND TABNAME = ’STAFF’ AND TABSCHEMA = ’SKAPOOR ’;
現(xiàn)在,將 FIRSTKEYCARD、FIRST2KEYCARD、FULLKEYCARD 和 NUMRIDS 從 35 修改為 37。現(xiàn)在保存 db2look.out 文件并運(yùn)行這 3 個(gè)文件:
db2 -tvf config.out > config_output.out db2 -tvf storage.out > storage_output.out db2 terminate db2stop db2start db2 -tvf db2look.out > db2look_output.out
檢查前兩個(gè)文件 config_output.out 和 storage_output.out 的內(nèi)容,以確保它們運(yùn)行成功,F(xiàn)在,檢查 db2look_output.out 文件的內(nèi)容。您將看到下列更新語(yǔ)句失敗了:
UPDATE SYSSTAT.INDEXES SET NLEAF=1, NLEVELS=1, FIRSTKEYCARD=37, FIRST2KEYCARD=37 , FIRST3KEYCARD=-1, FIRST4KEYCARD=-1, FULLKEYCARD=37, CLUSTERFACTOR=-1.000000, C LUSTERRATIO=100, SEQUENTIAL_PAGES=0, DENSITY=0, AVERAGE_SEQUENCE_GAP=0.000000, A VERAGE_SEQUENCE_FETCH_GAP=0.000000, AVERAGE_SEQUENCE_PAGES=0.000000, AVERAGE_SEQ UENCE_FETCH_PAGES=0.000000, AVERAGE_RANDOM_PAGES=1.000000, AVERAGE_RANDOM_FETCH_ PAGES=0.000000, NUMRIDS=37, NUMRIDS_DELETED=0, NUM_EMPTY_LEAFS=0 WHERE INDNAME = ’NAME_IND’ AND INDSCHEMA = ’SKAPOOR ’ AND TABNAME = ’STAFF’ AND TABSCHEMA = ’SK APOOR ’ DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL1227N The catalog statistic "37" for column "FULLKEYCARD" is out of range for its target column, has an invalid format, or is inconsistent in relation to some other statistic. Reason Code = "8". SQLSTATE=23521
正如您可以看到的,上面用于索引 NAME_IND 的 UPDATE 語(yǔ)句失敗了,因?yàn)?nbsp;FULLKEYCARD 大于表的基數(shù)(CARD)。正如通過(guò) db2look.out 文件中的下列更新語(yǔ)句可以看到的,CARD 是 35:
UPDATE SYSSTAT.TABLES SET CARD=35, NPAGES=1, FPAGES=1, OVERFLOW=0, ACTIVE_BLOCKS=0 WHERE TABNAME = ’STAFF’ AND TABSCHEMA = ’SKAPOOR ’;
現(xiàn)在,再次以解釋模式運(yùn)行相同的查詢(xún):
db2 "select name from staff where id=10 order by name"
并生成訪問(wèn)計(jì)劃。您將看到它是不同的:
Access Plan: ----------- Total Cost: 12.972 Query Degree: 1
Rows RETURN ( 1) Cost I/O | 1 TBSCAN ( 2) 12.972 1 | 1 SORT ( 3) 12.9708 1 | 1 TBSCAN ( 4) 12.9682 1 | 35 TABLE: SKAPOOR STAFF
該示例顯示,如果在表上發(fā)生 WRITE 活動(dòng)時(shí)運(yùn)行 RUNSTATS,統(tǒng)計(jì)數(shù)據(jù)就可能與本示例中的不一致。因此,用于更新統(tǒng)計(jì)數(shù)據(jù)的 UPDATE 語(yǔ)句可能失敗并產(chǎn)生 SQL1227N 錯(cuò)誤消息。所有的 UPDATE 語(yǔ)句都運(yùn)行成功十分重要,如果存在不一致性,就應(yīng)該進(jìn)行修理并重新運(yùn)行。本例中,解決方案是將 KEYCARDS 和 NUMRIDS 從 37 重新修改為 35。
|