2016-05-08 12 views
1

結果を生成せずにほぼ2時間実行されるクエリがあります。私は実行計画を取ったが、それは以下のように見える。 enter image description hereOracle Oracle DBのクエリのパフォーマンスチューニング

コード

このコードは、基本的には、ピボット操作ん:

SELECT y.COMPANYNAME as OIPACOMPANYNAME, 
     z.POLICYNUMBER as OIPAPOLICYNUMBER, 
     x.STATUSCODE as OIPASTATUSCODE, 
     MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='PolicyEffDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPAPOLICYEFFDATE, 
     x.ISSUESTATECODE as OIPAISSUESTATECODE, 
    NULL as OIPACURRENTSTATECODE, 
     MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='PolicyEndDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPAPOLICYENDDATE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='IssueAge' THEN w.INTVALUE 
     ELSE NULL 
     END) as OIPAISSUEAGE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='PolicyYear' THEN w.INTVALUE 
     ELSE NULL 
     END) as OIPAPOLICYYEAR, 
     V.PLANNAME AS OIPAPLANNAME, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='PolicyUniqueIdentifier' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAPOLUPI, 
    NULL as OIPAPLANMODALFACTOR, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='Participating' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAPARTICIPATING, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='Participating' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAREINSURANCETYPE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='BaseFaceAmount' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPABASEFACEAMOUNT, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='QualType' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAQUALTYPE, 
    NULL as OIPATAXQUALSALESMARKET, --- field record not found hence set as null 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='BillToDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPABILLTODATE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='PaidToDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPAPAIDTODATE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='PaymentMode' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAPAYMENTMODE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='PaymentMethod' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAPAYMENTMETHOD, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='BillingLeadDays' THEN w.INTVALUE 
     ELSE NULL 
     END) as "OIPABILLING LEAD DAYS", 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='BankDraftDay' THEN w.INTVALUE 
     ELSE NULL 
     END) as OIPABANKDRAFTDAY, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='EFTDraftCode' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAEFTDRAFTCODE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='CurrentModalPremiumAmt' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPACURRENTMODALPREMIUMAMT, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='CurrentAnnualPremiumAmt' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPACURRENTANNUALPREMIUMAMT, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='PolicyModalPremiumAdjustment' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPAPOLICYMODALPREMIUMADJ, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='PolicyFee' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPAPOLICYFEE, 
    NULL as OIPALOANPRINCIPAL, 
    NULL as OIPAOUTSTANDINGLOAN, 
    NULL as OIPALOANINTERESTDUE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='LoanInterestRate' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPALOANINTERESTRATE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='LoanInterestType' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPALOANINTERESTTYPE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='APLIndicator' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPAAPLINDICATOR, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='LoanBankDraftDay' THEN w.INTVALUE 
     ELSE NULL 
     END) as OIPALOANBANKDRAFTDAY, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='LoanPaymentMethod' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPALOANPAYMENTMETHOD, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='LoanPaymentMode' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPALOANPAYMENTMODE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='LoanModalPaymentAmount' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPALOANMODALPAYMENTAMOUNT, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='03' AND w.FIELDNAME='LoanBillingLeadDays' THEN w.INTVALUE 
     ELSE NULL 
     END) as OIPALOANBILLINGLEADDAYS, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='LoanBillingDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPALOANBILLINGDATE, 
    NULL as OIPAPITCASHVALUE, 
    NULL as OIPAPITCASHSURRVALUE, 
    NULL as OIPANXTMODVARCASHVALUE, 
    NULL as OIPAPITDIVONDEP, 
    NULL as OIPAPITINTONDEP, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='DividendOptionPrimary' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDOPTIONPRIMARY, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='DividendOptionSecondary' THEN w.TEXTVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDOPTIONSECONDARY, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendToApplyToCash' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDTOAPPLYTOCASH, 
    NULL as OIPADIVIDENDTOAPPLYTOACCUDIV, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendToApplyToLoan' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDTOAPPLYTOLOAN, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendToApplyToOYT' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDTOAPPLYTOOYT, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendToApplyToPremium' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDTOAPPLYTOPREMIUM, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendToApplyToPUA' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDTOAPPLYTOPUA, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='DividendInterestRate' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDINTERESTRATE, 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='01' AND w.FIELDNAME='DividendDeclaredDate' THEN w.DATEVALUE 
     ELSE NULL 
     END) as OIPADIVIDENDDECLAREDDATE, 
    NULL as OIPAPUA, 
    NULL as OIPAPUAPURCHASEDLASTANN,----- field record not found hence set as null 
    NULL as OIPAOYT,--field record not found hence set as null 
    NULL as OIPAEICTOAPPLYTOOYT,--- field record not found hence set as null 
    MAX(CASE 
     WHEN w.FIELDTYPECODE='04' AND w.FIELDNAME='NetCostBasis' THEN w.FLOATVALUE 
     ELSE NULL 
     END) as OIPANETCOSTBASIS, 


    a.SEGMENTGUID as "OIPASEGMENTGUID", 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='02' AND b.FIELDNAME='SegmentFormerSystemPlanCode' THEN b.TEXTVALUE 
     ELSE NULL 
     END) as "OIPASEGMENTFORMERSYSTEMPLAN", 
    c.SEGMENTNAME as "OIPASEGMENTNAME", 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='02' AND b.FIELDNAME='SegmentStatusCode' THEN b.TEXTVALUE 
     ELSE NULL 
     END) as "OIPASEGMENTSTATUSCODE", 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='01' AND b.FIELDNAME='SegmentIssueDate' THEN b.DATEVALUE 
     ELSE NULL 
     END) as "OIPASEGMENTISSUEDATE", 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='01' AND b.FIELDNAME='SegmentEndDate' THEN b.DATEVALUE 
     ELSE NULL 
     END) as "OIPASEGMENTENDDATE", 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='01' AND b.FIELDNAME='SegmentTerminationDate' THEN b.DATEVALUE 
     ELSE NULL 
     END) as OIPASEGMENTTERMINATIONDATE, 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='03' AND b.FIELDNAME='SegmentIssueAge' THEN b.INTVALUE 
     ELSE NULL 
     END) as OIPASEGMENTISSUEAGE, 
    MAX(CASE 
     WHEN b.FIELDTYPECODE='03' AND b.FIELDNAME='BaseIssueAge' THEN b.INTVALUE 
     ELSE NULL 
     END) as OIPABASEISSUEAGE 
    FROM ASPOLICY x LEFT JOIN ASCOMPANY y ON (x.COMPANYGUID=y.COMPANYGUID) 
    INNER JOIN AUDIT_EXT_TEMP_BULK Z ON (z.COMPANYGUID=y.COMPANYGUID and x.POLICYGUID=Z.POLICYGUID) 
    LEFT JOIN ASPOLICYFIELD w ON (W.POLICYGUID=z.POLICYGUID) 
    LEFT JOIN ASPLAN v ON (v.PLANGUID=x.PLANGUID AND v.COMPANYGUID=z.COMPANYGUID) -- Plan Information 
    LEFT JOIN ASSEGMENT a ON (x.POLICYGUID=a.POLICYGUID) -- Segment 
    LEFT JOIN ASSEGMENTFIELD b ON (b.SEGMENTGUID=a.SEGMENTGUID) -- Segment 
    LEFT JOIN ASSEGMENTNAME c ON (c.SEGMENTNAMEGUID=a.SEGMENTNAMEGUID) 
    GROUP BY y.COMPANYNAME, 

      z.POLICYNUMBER, 

      x.STATUSCODE, 

      x.ISSUESTATECODE, 

      v.PLANNAME, 

      a.SEGMENTGUID, 

      c.SEGMENTNAME; 

ここでは、読みやすくするために露出の文の末尾である:

FROM ASPOLICY x LEFT JOIN ASCOMPANY y ON (x.COMPANYGUID=y.COMPANYGUID) 
INNER JOIN AUDIT_EXT_TEMP_BULK Z ON (z.COMPANYGUID=y.COMPANYGUID 
             and x.POLICYGUID=Z.POLICYGUID) 
LEFT JOIN ASPOLICYFIELD w ON (W.POLICYGUID=z.POLICYGUID) 
LEFT JOIN ASPLAN v ON (v.PLANGUID=x.PLANGUID 
         AND v.COMPANYGUID=z.COMPANYGUID) -- Plan Information 
LEFT JOIN ASSEGMENT a ON (x.POLICYGUID=a.POLICYGUID) -- Segment 
LEFT JOIN ASSEGMENTFIELD b ON (b.SEGMENTGUID=a.SEGMENTGUID) -- Segment 
LEFT JOIN ASSEGMENTNAME c ON (c.SEGMENTNAMEGUID=a.SEGMENTNAMEGUID) 
GROUP BY y.COMPANYNAME, 
     z.POLICYNUMBER, 
     x.STATUSCODE, 
     x.ISSUESTATECODE, 
     v.PLANNAME, 
     a.SEGMENTGUID, 
     c.SEGMENTNAME; 

テーブルは以下のインデックスを持っていますここで、矢印の左側が表を表し、右側がindその上にex。ご注意:dbms_stats.gather_table_stats('schema','table name');

AUDIT_EXT_TEMP_BULK-->COMPANYGUID,POLICYGUID); 

ASPLAN-->PLANGUID 

ASPOLICY-->COMPANYGUID 

ASCOMPANY-->COMPANYGUID 

ASPOLICYFIELD-->POLICYGUID 

ASSEGMENT-->POLICYGUID 

ASSEGMENTFIELD-->SEGMENTGUID 

ASSEGMENTNAME-->SEGMENTNAMEGUID 

答えて

3

を実行して、私はテーブルの統計を更新したクエリを実行する前に、

だから、それが実際に何を作成しようとする試みがある「このコードは、基本的には、ピボット操作ません」コヒーレント結果セットはan Entity-Attribute-Value modelから設定されます。これらは、調律することは悪名高く難しいです。 EAVは分析などの特定のユースケースに適していますが、原子化された列のセットから行を再構築するのは非常に高価です。再構築は手動のプロセスであるので、彼らは、また、エラーが発生しやすい(!あなたが今実現される)も照会することが面倒であり、 - これはおそらくあなたがOIPAREINSURANCETYPEのために戻すために必要なものではありません。

MAX(CASE 
    WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='Participating' THEN w.TEXTVALUE 
    ELSE NULL 
    END) as OIPAPARTICIPATING, 
MAX(CASE 
    WHEN w.FIELDTYPECODE='02' AND w.FIELDNAME='Participating' THEN w.TEXTVALUE 
    ELSE NULL 
    END) as OIPAREINSURANCETYPE, 

これは実証しますそれが使用されている場合のほとんどの場合、EAVの不適当です。スキーマはまだ修正されていますが、書き込みの代わりに読み込みにハードコードされています。

もちろん、EAVは「モデル」をクエリする必要があるだけでなく、データベースがデータの格納方法を理解することも不可能になり、不正な実行計画が生成されます。

私は感心していることを認めます:Gを最後に覚えていません。Rowsの説明書の列にあります。つまり、あなたの説明は、あなたの質問が〜923,000,000,000行となり、GROUP BYが唯一〜7,879,000,000行にまで激減することを示しています。

どのくらいのデータが返されたら、どれくらいの時間がかかると思いますか?

おそらく、最終的な数字があなたを驚かせます。間違いなく、7789個の行(ポリシーごとに1つ)を期待していたことは間違いありません。代わりにあなたは怪物のデカルト製品を持っています。これらの余分な行はどこから来ますか?

問題の1つは、AUDIT_EXT_TEMP_BULKの参加です。このテーブルにはフィルタがないため、ポリシーごとに800行以上が追加されます。これは、ポリシー番号を取得するための高価な方法ですが、これはおそらくすべてのポリシーで固定されています。

INNER JOIN (select distinct COMPANYGUID, POLICYGUID, POLICYNUMBER 
     from AUDIT_EXT_TEMP_BULK Z) 
ON (z.COMPANYGUID=y.COMPANYGUID and x.POLICYGUID=Z.POLICYGUID) 

もう一つは、次のとおりです。この一つの値を取得するために、より賢明な方法がない場合は数字にかなり減らす必要があるのインラインビューでそのテーブルを置き換える(ASPOLICY表の列を言います) GROUP BY:あなたは実際にはこれらの列を上集約する必要があります。

y.COMPANYNAME as OIPACOMPANYNAME, 
z.POLICYNUMBER as OIPAPOLICYNUMBER, 
x.STATUSCODE as OIPASTATUSCODE 

かなり大幅に計画を説明し改善するかもしれない他の列を削除します。

+0

大きな説明をいただきありがとうございます。私はあなたの提案を明日(月曜日)に組み込み、起こったことを投稿します。 – redsoxlost