アップデート2011年1月31日オラクルMAX()のバグは、インデックスの制限につながる
私はDBの制限に対して実行していると思います。 GROUP BY式
とすべての非統一集計関数は、単一の
データベースブロックを超えている可能性があります。
は、オリジナルポストhttp://download.oracle.com/docs/cd/B19306_01/server.102/b14237/limits003.htm
を参照してください: - のProd
これは、Oracle Database 10g Enterprise Editionのリリース10.2.0.1.0です。
次のインサートは、真MAXを(戻らない)私はcontributionP NULL値と非NULL値を持つ相互matchKeyが同じである二つのレコード一
を持っている場合
値。
MAX()が返す値がNULL値であることがあります。
INSERT /*+ APPEND */ INTO meCostingXPrePre(
matchKey ,
contributionP ,
stimulusContributionP ,
contributionC ,
ageMultiplier ,
rateTableIdP ,
rateTableIdC ,
accountNbrP ,
accountNbrC ,
commissionExpenseAccount ,
commissionReceivableAccount ,
commissionType ,
commission ,
pmPm ,
fee ,
planAgeGroupIdP ,
planAgeGroupIdC ,
rafP ,
rafC ,
nbrEmployeesRafP ,
nbrEmployeesRafC ,
contractId ,
basePlanId ,
groupOrPolicyNumber ,
planCoverageDescription ,
cobraGopn ,
cobraPcd ,
cobraCid ,
benefitId ,
insuranceStart ,
insuranceEnd ,
categoryId )
SELECT
matchKey as matchKey ,
MAX(NVL(contributionP ,0)) as contributionP ,
MAX(NVL(stimulusContributionP ,0)) as stimulusContributionP ,
MAX(NVL(contributionC ,0)) as contributionC ,
MAX(NVL(ageMultiplier ,0)) as ageMultiplier ,
MAX(NVL(rateTableIdP ,0)) as rateTableIdP ,
MAX(NVL(rateTableIdC ,0)) as rateTableIdC ,
MAX(NVL(accountNbrP ,0)) as accountNbrP ,
MAX(NVL(accountNbrC ,0)) as accountNbrC ,
MAX(NVL(commissionExpenseAccount ,0)) as commissionExpenseAccount ,
MAX(NVL(commissionReceivableAccount ,0)) as commissionReceivableAccount ,
MAX(NVL(commissionType ,0)) as commissionType ,
MAX(NVL(commission ,0)) as commission ,
MAX(NVL(pmPm ,0)) as pmPm ,
MAX(NVL(fee ,0)) as fee ,
MAX(NVL(planAgeGroupIdP ,0)) as planAgeGroupIdP ,
MAX(NVL(planAgeGroupIdC ,0)) as planAgeGroupIdC ,
MAX(NVL(rafP ,0)) as rafP ,
MAX(NVL(rafC ,0)) as rafC ,
MAX(NVL(nbrEmployeesRafP ,0)) as nbrEmployeesRafP ,
MAX(NVL(nbrEmployeesRafC ,0)) as nbrEmployeesRafC ,
CASE WHEN MAX(contractId) IS NOT NULL AND
MIN(contractId) IS NOT NULL AND
MAX(contractId) != MIN(contractId) THEN
CASE WHEN MAX(contractId) = 'No Contract No' THEN
MIN(contractId)
WHEN MIN(contractId) = 'No Contract No' THEN
MAX(contractId)
ELSE
MAX(contractId)
END
ELSE
MAX(contractId)
END as contractId ,
MAX(NVL(basePlanId ,0)) as basePlanId ,
CASE WHEN MAX(groupOrPolicyNumber) IS NOT NULL AND
MIN(groupOrPolicyNumber) IS NOT NULL AND
MAX(groupOrPolicyNumber) != MIN(groupOrPolicyNumber) THEN
CASE WHEN MAX(groupOrPolicyNumber) = 'No Contract No' THEN
MIN(groupOrPolicyNumber)
WHEN MIN(groupOrPolicyNumber) = 'No Contract No' THEN
MAX(groupOrPolicyNumber)
ELSE
MAX(groupOrPolicyNumber)
END
ELSE
MAX(groupOrPolicyNumber)
END as groupOrPolicyNumber ,
CASE WHEN MAX(planCoverageDescription) IS NOT NULL AND
MIN(planCoverageDescription) IS NOT NULL AND
MAX(planCoverageDescription) != MIN(planCoverageDescription) THEN
CASE WHEN MAX(planCoverageDescription) = 'No Contract No' THEN
MIN(planCoverageDescription)
WHEN MIN(planCoverageDescription) = 'No Contract No' THEN
MAX(planCoverageDescription)
ELSE
MAX(planCoverageDescription)
END
ELSE
MAX(planCoverageDescription)
END as planCoverageDescription ,
CASE WHEN MAX(cobraGopn) IS NOT NULL AND
MIN(cobraGopn) IS NOT NULL AND
MAX(cobraGopn) != MIN(cobraGopn) THEN
CASE WHEN MAX(cobraGopn) = 'No Contract No' THEN
MIN(cobraGopn)
WHEN MIN(cobraGopn) = 'No Contract No' THEN
MAX(cobraGopn)
ELSE
MAX(cobraGopn)
END
ELSE
MAX(cobraGopn)
END as cobraGopn ,
CASE WHEN MAX(cobraPcd) IS NOT NULL AND
MIN(cobraPcd) IS NOT NULL AND
MAX(cobraPcd) != MIN(cobraPcd) THEN
CASE WHEN MAX(cobraPcd) = 'No Contract No' THEN
MIN(cobraPcd)
WHEN MIN(cobraPcd) = 'No Contract No' THEN
MAX(cobraPcd)
ELSE
MAX(cobraPcd)
END
ELSE
MAX(cobraPcd)
END as cobraPcd ,
CASE WHEN MAX(cobraCid) IS NOT NULL AND
MIN(cobraCid) IS NOT NULL AND
MAX(cobraCid) != MIN(cobraCid) THEN
CASE WHEN MAX(cobraCid) = 'No Contract No' THEN
MIN(cobraCid)
WHEN MIN(cobraCid) = 'No Contract No' THEN
MAX(cobraCid)
ELSE
MAX(cobraCid)
END
ELSE
MAX(cobraCid)
END as cobraCid ,
MAX(benefitId ) as benefitId ,
NULL as insuranceStart ,
NULL as insuranceEnd ,
NULL as categoryId
FROM meCostingXPrePrePre
GROUP BY matchKey;
私は次のようにインデックスを構築し、CBOのヒントに
CREATE INDEX C$MECOSTINGXPREPREPRE$MULTI0 ON MECOSTINGXPREPREPRE
(MATCHKEY, CONTRIBUTIONP, STIMULUSCONTRIBUTIONP, CONTRIBUTIONC, AGEMULTIPLIER,
RATETABLEIDP, RATETABLEIDC, ACCOUNTNBRP, ACCOUNTNBRC, COMMISSIONEXPENSEACCOUNT,
COMMISSIONRECEIVABLEACCOUNT, COMMISSIONTYPE, COMMISSION, PMPM, FEE,
PLANAGEGROUPIDP, PLANAGEGROUPIDC, RAFP, RAFC,
NBREMPLOYEESRAFP, NBREMPLOYEESRAFC, CONTRACTID, BASEPLANID, GROUPORPOLICYNUMBER,
PLANCOVERAGEDESCRIPTION, COBRAGOPN, COBRAPCD, COBRACID, BENEFITID)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
INSERT /*+ APPEND */ INTO meCostingXPrePre(
...)
SELECT /*+ INDEX(meCostingXPrePrePre c$mecostingxpreprepre$multi0) */
...
FROM meCostingXPrePrePre
GROUP BY matchKey;
を与える場合はこれが正しく動作するようにMAXを()を取得します。
私はインデックス小さな問題
CREATE INDEX C$MECOSTINGXPREPREPRE$MULTI0 ON MECOSTINGXPREPREPRE
(MATCHKEY, CONTRIBUTIONP, STIMULUSCONTRIBUTIONP, CONTRIBUTIONC, AGEMULTIPLIER,
RATETABLEIDP, RATETABLEIDC, ACCOUNTNBRP, ACCOUNTNBRC, COMMISSIONEXPENSEACCOUNT,
COMMISSIONRECEIVABLEACCOUNT, COMMISSIONTYPE, COMMISSION, PMPM, FEE,
PLANAGEGROUPIDP, PLANAGEGROUPIDC, ADDRESSONEP, ADDRESSONEC, ADDRESSTWOP,
ADDRESSTWOC, CITYP, CITYC, STATEP, STATEC, ZIPFULLP, ZIPFULLC, RAFP, RAFC,
NBREMPLOYEESRAFP, NBREMPLOYEESRAFC, CONTRACTID, BASEPLANID, GROUPORPOLICYNUMBER,
PLANCOVERAGEDESCRIPTION, COBRAGOPN, COBRAPCD, COBRACID, BENEFITID)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
が
ORA-01793を与える15個の余分な列を追加し、変更する必要が
:インデックス列の最大数は32
まずMAX(あり)大きな列セットでは機能せず、インデックス+ CBOパッチ
はインデックス制限につながります。
提案がありますか?
「私は15の余分な列を追加する必要がある」 - これらは、ほとんどNEVべき言葉...ないです。 ..話さない。すでに使用されているテーブルに15個のカラムを追加している場合、あなたのデザインに問題があります。あなたが15列*を持っているならば、あなたが正規化できる場所を調べることを検討すべきです。 –
MAX(NVL(cobraPcd、 ''))とは何ですか? Oracleでは ''はNULLと同じですので、NVL(cobraPcd、 '')は_cobraPcd_と同じです。とにかく、MAXはNULL値を処理します。 – Codo
このバグはMetalinkに記載されていますか?それを再現するための簡単な*(それほど多くの列ではない)テストケースを考え出すことができますか? – Dan