更新2011年1月31日甲骨文MAX()的臭蟲以NULL值CBO指數修正導致指數限制
我想我競選對手一個DB限制。的GROUP BY表達
和所有nondistinct集合函數可能已超出單個
數據庫塊。
見http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/limits003.htm
原帖:
這是Oracle數據庫10g企業版發佈10.2.0.1.0 - PROD。
下插入不返回真正的MAX()值
如果我有兩個記錄中,其中matchKey是一樣的,一個
與contributionP NULL值,另外一非NULL值。
有時,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()到正常運行。
我需要添加15多列,並更改索引
小問題
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:索引列的最大數量爲32
首先MAX()不與大列集和第二工作,該指數+ CBO修補
導致指數的限制。
有什麼建議嗎?
「我需要添加額外的15列」 - 這些話應該幾乎內華達州...沒有。 ..不說話。如果您將* 15個列添加到已經在使用的表格*,那麼您的設計存在問題。如果你有15列*,你應該考慮看看你可以在哪裏歸一化。 – 2011-01-28 19:12:09
MAX(NVL(cobraPcd,''))應該做什麼?在Oracle中,''與NULL相同,因此NVL(cobraPcd,'')與_cobraPcd_相同。無論如何,MAX都處理NULL值。 – Codo 2011-01-28 19:40:43
Metalink上列出了這個錯誤嗎?你能想出一個簡單的*(意思是沒有那麼多列)測試用例來重現它嗎? – Dan 2011-01-28 19:49:08