Szenario: Verbessern der Kardinalitätsschätzung durch Statistiksichten
In einem Data-Warehouse ändern sich die Informationen von Fakttabellen in der Regel recht dynamisch, während die Daten von Dimensionstabellen eher statischen Charakter haben. Daher können Attributdaten für Dimensionen häufig positiv oder negativ mit Attributdaten von Fakttabellen korreliert sein.
Die gegenwärtig für das Optimierungsprogramm verfügbaren traditionellen Statistikdaten für Basistabellen geben dem Optimierungsprogramm keine Möglichkeit, tabellenübergreifende Beziehungen zu erkennen. Verteilungsstatistiken zu Spalten und Tabellen für Statistiksichten (und MQTs) können dazu genutzt werden, die erforderlichen Informationen für das Optimierungsprogramm bereitzustellen, um derartige Kardinalitätsschätzfehler zu korrigieren.
select sum(f.sales_price), d2.year
from product d1, period d2, daily_sales f
where d1.prodkey = f.prodkey
and d2.perkey = f.perkey
and d1.item_desc = 'golf club'
and d2.month = 'JUL'
group by d2.yearEin Abfrageausführungsplan mit Sternjoin kann eine gute Wahl für diese Abfrage sein, sofern das Optimierungsprogramm feststellen kann, ob die einfache Gleichheitsverknüpfung (Semi-Join) von PRODUCT und DAILY_SALES oder die einfache Gleichheitsverknüpfung von PERIOD und DAILY_SALES die höhere Selektivität erzielt. Um einen effizienten Sternjoinplan generieren zu können, muss das Optimierungsprogramm in der Lage sein, die selektivste Semi-Join-Verknüpfung für den äußeren Part der logischen Indexverknüpfungsoperation über AND auszuwählen.
Data-Warehouses enthalten häufig Datensätze für Produkte, die nicht länger in den
Geschäftsregalen verfügbar sind. Dies kann dazu führen, dass die Verteilung von PRODUCT-Spalten nach dem Join völlig anders aussieht
als ihre Verteilung vor dem Join. Da das Optimierungsprogramm aus Mangel an besseren Informationen die Selektivität lokaler Vergleichselemente ausschließlich auf der Basis von Basistabellenstatistiken bestimmt, kann das Optimierungsprogramm in Bezug auf die Selektivität des Vergleichselements zu optimistisch werden. item_desc
= 'golf club'
Wenn Golfschläger historisch betrachtet zum Beispiel 1 % der hergestellten Produkte
darstellen, jedoch jetzt 20 % der Umsätze ausmachen, würde das Optimierungsprogramm
mit hoher Wahrscheinlichkeit die Selektivität des Vergleichselements
item_desc = 'golf club' überschätzen, da keine Statistikdaten
vorhanden sind, die die Verteilung von item_desc nach dem Join
beschreiben. Und wenn außerdem die Umsätze in allen zwölf Monaten gleichermaßen wahrscheinlich
sind, läge die Selektivität des Vergleichselements month = 'JUL' bei
ca. 8 %. Daher würde der Schätzfehler für die Selektivität des Vergleichselements
item_desc = 'golf club' das Optimierungsprogramm fälschlicherweise
dazu veranlassen, die scheinbar selektivere Semi-Join-Operation zwischen PRODUCT und DAILY_SALES
als äußeren Part der logischen AND-Verknüpfung der Indizes des Sternjoinplans auszuführen.
Im folgenden Beispiel wird die Bereitstellung von Statistiksichten zur Lösung dieses Typs von Problem schrittweise veranschaulicht.
| Spalte | storekey | store_number | city | Status | district | ... |
|---|---|---|---|---|---|---|
| Attribut | Ganze Zahl
ungleich null Primärschlüssel |
char(2) | char(20) | char(5) | char(14) | ... |
| Spalte | custkey | Name | address | age | gender | ... |
|---|---|---|---|---|---|---|
| Attribut | Ganze Zahl
ungleich null Primärschlüssel |
char(30) | char(40) | smallint | char(1) | ... |
| Spalte | prodkey | Kategorie | item_desc | price | cost | ... |
|---|---|---|---|---|---|---|
| Attribut | Ganze Zahl
ungleich null Primärschlüssel |
ganze Zahl | char(30) | decimal(11) | decimal(11) | ... |
| Spalte | promokey | promotype | promodesc | promovalue | ... |
|---|---|---|---|---|---|
| Attribut | Ganze Zahl
ungleich null Primärschlüssel |
ganze Zahl | char(30) | decimal(5) | ... |
| Spalte | perkey | calendar_date | Monat | Rechnungslegungszyklus | Jahr | ... |
|---|---|---|---|---|---|---|
| Attribut | Ganze Zahl
ungleich null Primärschlüssel |
Datum | char(3) | smallint | smallint | ... |
| Spalte | storekey | custkey | prodkey | promokey | perkey | sales_price | ... |
|---|---|---|---|---|---|---|---|
| Attribut | ganze Zahl | ganze Zahl | ganze Zahl | ganze Zahl | ganze Zahl | decimal(11) | ... |
Nehmen Sie an, die Unternehmensmanager möchten feststellen, ob Kunden ein Produkt noch einmal kaufen, wenn ihnen ein Rabatt bei einem weiteren Besuch angeboten wird. Nehmen Sie außerdem an, dass diese Studie nur für das Geschäft (STORE) '01' durchgeführt wird, das 18 Niederlassungen im Land hat. Tabelle 7 enthält Informationen zu den verschiedenen verfügbaren Rabattkategorien.
| promotype | promodesc | COUNT (promotype) | Prozentsatz vom Gesamtwert |
|---|---|---|---|
| 1 | Return customers | 1 | 2.86% |
| 2 | Coupon | 15 | 42.86% |
| 3 | Advertisement | 5 | 14.29% |
| 4 | Manager's special | 3 | 8.57% |
| 5 | Overstocked items | 4 | 11.43% |
| 6 | End aisle display | 7 | 20.00% |
select count(*)
from store d1, promotion d2, daily_sales f
where d1.storekey = f.storekey
and d2.promokey = f.promokey
and d1.store_number = '01'
and d2.promotype = 1 6.15567e+06
IXAND
( 8)
/------------------+------------------\
2.15448e+07 2.15448e+08
NLJOIN NLJOIN
( 9) ( 13)
/---------+--------\ /---------+--------\
1 2.15448e+07 18 1.19694e+07
FETCH IXSCAN FETCH IXSCAN
( 10) ( 12) ( 14) ( 16)
/---+---\ | /---+---\ |
35 35 7.54069e+08 18 63 7.54069e+08
IXSCAN TABLE: DB2DBA INDEX: DB2DBA IXSCAN TABLE: DB2DBA INDEX: DB2DBA
( 11) PROMOTION PROMO_FK_IDX ( 15) STORE STORE_FK_IDX
| |
35 63
INDEX: DB2DBA INDEX: DB2DBA
PROMOTION_PK_IDX STOREX1| Vor dem Join | Nach dem Join | |||
|---|---|---|---|---|
| Vergleichselement | Zähler | Prozentsatz qualifizierter Zeilen | Zähler | Prozentsatz qualifizierter Zeilen |
| store_number = '01' | 18 | 28.57% | 2.15448e+08 | 28.57% |
| promotype = 1 | 1 | 2.86% | 2.15448e+07 | 2.86% |
Da die Wahrscheinlichkeit von promotype = 1 geringer ist als die
von store_number = '01', wählt das Optimierungsprogramm die
Semi-Join-Verknüpfung zwischen den Tabellen PROMOTION und DAILY_SALES als äußeren Teil der
logischen AND-Verknüpfung von Indizes des Sternjoinplans. Dies führt zu einer geschätzten Anzahl
von ca. 6.155.670 Produkten, die über den Verkaufsförderungstyp 1 verkauft wurden. Diese inkorrekte
Kardinalitätsschätzung liegt um den Faktor 2,09 (12.889.514 ÷ 6.155.670 ≈ 2,09) unter der tatsächlichen Anzahl.
- Erstellen Sie eine Sicht, die den Join der Tabelle STORE mit der Tabelle DAILY_SALES darstellt.
create view sv_store_dailysales as (select s.* from store s, daily_sales ds where s.storekey = ds.storekey) - Erstellen Sie eine Sicht, die den Join der Tabelle PROMOTION mit der Tabelle DAILY_SALES darstellt.
create view sv_promotion_dailysales as (select p.* from promotion.p, daily_sales ds where p.promokey = ds.promokey) - Machen Sie die Sichten zu Statistiksichten, indem Sie sie für die Abfrageoptimierung aktivieren:
alter view sv_store_dailysales enable query optimization alter view sv_promotion_dailysales enable query optimization - Führen Sie das Dienstprogramm RUNSTATS aus, um Statistikdaten für die Sichten zu erfassen:
runstats on table db2dba.sv_store_dailysales with distribution runstats on table db2dba.sv_promotion_dailysales with distribution - Führen Sie die Abfrage erneut aus, damit sie erneut optimiert werden kann. Bei der Reoptimierung gleicht
das Optimierungsprogramm die Sicht SV_STORE_DAILYSALES und die Sicht SV_PROMOTION_DAILYSALES mit der Abfrage
ab und verwendet die Statistikdaten für die Sichten, um die Kardinalitätsschätzung der
Semi-Join-Verknüpfungen zwischen der Fakttabelle und den Dimensionstabellen anzupassen. Dies führt zu einer
Umkehrung der Reihenfolge der Semi-Join-Verknüpfungen, die ohne diese Statistiken ausgewählt wurden. Der neue Plan
sieht folgendermaßen aus:
1.04627e+07 IXAND ( 8) /------------------+------------------\ 6.99152e+07 1.12845e+08 NLJOIN NLJOIN ( 9) ( 13) /---------+--------\ /---------+--------\ 18 3.88418e+06 1 1.12845e+08 FETCH IXSCAN FETCH IXSCAN ( 10) ( 12) ( 14) ( 16) /---+---\ | /---+---\ | 18 63 7.54069e+08 35 35 7.54069e+08 IXSCAN TABLE:DB2DBA INDEX: DB2DBA IXSCAN TABLE: DB2DBA INDEX: DB2DBA DB2DBA ( 11) STORE STORE_FK_IDX ( 15) PROMOTION PROMO_FK_IDX | | 63 35 INDEX: DB2DBA INDEX: DB2DBA STOREX1 PROMOTION_PK_IDX
| Vor dem Join | Nach dem Join (ohne Statistiksichten) | Nach dem Join (mit Statistiksichten) | ||||
|---|---|---|---|---|---|---|
| Vergleichselement | Zähler | Prozentsatz qualifizierter Zeilen | Zähler | Prozentsatz qualifizierter Zeilen | Zähler | Prozentsatz qualifizierter Zeilen |
| store_number = '01' | 18 | 28.57% | 2.15448e+08 | 28.57% | 6.99152e+07 | 9.27% |
| promotype = 1 | 1 | 2.86% | 2.15448e+07 | 2.86% | 1.12845e+08 | 14.96% |
store_number = '01' mehr Zeilen filtert als promotype = 1. Dieses Mal schätzt das Optimierungsprogramm, dass ungefähr 10 462 700 Produkte verkauft werden. Diese Schätzung ist um den Faktor 1.23 (12 889 514 ÷ 10 462 700 ≈ 1.23) inaktiviert, was eine signifikante Verbesserung gegenüber der Schätzung ohne Statistiksichten (in Tabelle 8) darstellt.