【问题标题】:How to convert to Materialized view query with bind variables如何使用绑定变量转换为物化视图查询
【发布时间】:2020-12-18 04:17:42
【问题描述】:

我的环境:

  • Azure IaaS 上的 Oracle 企业版 12.2
  • Linux Red Hat 版本 7
  • 内存:32GB
  • CPU:8 个 vCPU
  • 内存目标设置为 16GB。

让我解释一下这个问题。我在通过 Azure Kubernetes 中的 REST 服务运行的大查询时遇到了一些问题。该查询使用了很多表,并且在未设置绑定变量的情况下需要很长时间。实际上,当通知绑定变量时,查询只需要 1.5 秒。我试图说服开发查询的团队强制通知参数,但他们说需求是原样的,不能挑战。

我通过创建一些不存在的索引尽可能地改进了查询,即使我运行了一个 sql 调整任务来收集更多详细信息。我什至尝试根据 Tuning Advisor 的建议创建一个新的 sql 配置文件,但它使查询变得更慢,所以最后我放弃了它。当没有绑定值的查询单独运行时,需要 14 秒才能完成。但是,当同一个查询是海量压力测试的一部分(同时有 10 到 15 个威胁)时,一些进程会因超时而死亡,因此查询达到 60 秒而没有完成。

我一直看到相同的等待事件:PGA 内存操作(在这方面,我也尝试设置更多 PGA,我什至增加了隐藏参数 _pga_max_size_smm_max_size 的默认值。我也尝试使用手动工作区设置运行它,我禁用了pga_aggregated_limit,但它没有使查询运行得更快或更慢。

再次澄清一下:当查询没有将变量设置为特定值时,就会出现问题。只有在这种情况下我才会遇到问题。

我的最后一个想法是创建一个在提交时快速刷新的物化视图。数据库上的 DML 活动非常少,因此数据并发不会成为问题,我相信不会因此产生太多锁定。我读到自 11g 以来,Oracle 在提交时的快速刷新方面已经有了很大的改进。但是,我不知道我应该如何解决它。我应该使用整个查询创建一个 MVIEW 还是应该拆分它?

我想听听您对此事的意见。或者即使您看到可以优化的东西。不要犹豫,要求任何澄清。我尝试将执行计划添加到问题中,但我达到了最大正文字符限制。

非常感谢您的支持。

查询如下:

WITH extDealer
AS (SELECT thirdPartynumber
      FROM    ALFAODS.ODSEXTERNALSYSTEMREFERENCE odsExt
           INNER JOIN
              ALFAODS.OdsThirdParty thirdParty
           ON odsExt.THIRDPARTYID = thirdParty.id
     WHERE odsExt.reference = :1),
selection
AS 
(  SELECT schedule.maturityDate,
                  schedule.id AS schedule_id,
                  schedule.alfascheduleidentifier AS scheduleId,
                  asset.assetidentifier AS assetId,
                  agreement.agreementNumber AS loanId,
                  proposalStatus.DETAIL AS proposalStatusCode,
                  schedule.scheduleStatus AS scheduleStatus,
                  schedule.terminationDate,
                  (CASE
                      WHEN supplier.thirdPartyNumber =
                              thirdPartyDealer.thirdPartyNumber
                      THEN
                         TO_CHAR (supplier.thirdPartyNumber)
                      ELSE
                         '0'
                   END)
                     AS "supplierGPNr",
                  (CASE
                      WHEN proposalStatus.DETAIL = 'RESERVED'
                      THEN
                         '0'
                      WHEN proposalStatus.DETAIL = 'APPROVED'
                      THEN
                         '1'
                      WHEN proposalStatus.DETAIL = 'FINANCED'
                      THEN
                         '2'
                      WHEN proposalStatus.DETAIL = 'CANCELLED'
                      THEN
                         '3'
                      WHEN proposalStatus.DETAIL = 'PRECANCELLED'
                      THEN
                         '3'
                      WHEN proposalStatus.DETAIL = 'CREDITNOTECANCELLED'
                      THEN
                         '3'
                      WHEN proposalStatus.DETAIL = 'WAITING'
                      THEN
                         '4'
                      ELSE
                         '5'
                   END)
                     AS loanState,
                  productId1.DETAIL AS productId1,
                  productId2.DETAIL AS productId2,
                  productId3.DETAIL AS productId3,
                  productId4.DETAIL AS productId4,
                  productId.DETAIL AS wmProductId,
                  asset.serialNumber AS vin,
                  asset.modelName AS modelName,
                  schedule.totalAssetCostFinanced AS loanAmount,
                  (CASE
                      WHEN schedule.capitalOutstanding IS NULL
                      THEN
                         0
                      WHEN schedule.scheduleStatus = 'Proposal'
                      THEN
                         (CASE
                             WHEN proposalStatus.DETAIL = 'WAITING' THEN 0
                             ELSE schedule.capitalOutstanding * (-1)
                          END)
                      ELSE
                         schedule.capitalOutstanding * (-1)
                   END)
                     AS balance,
                  thirdPartyDealer.thirdPartyNumber AS dealerGPNr,
                  thirdPartyDealer.name AS dealerNameShort,
                  TO_DATE (
                     CAST (
                        CASE
                           WHEN (creationDate.DATEFIELD = 0) THEN NULL
                           ELSE creationDate.DATEFIELD
                        END AS NVARCHAR2 (8)),
                     'yyyymmdd')
                     AS creationDate,
                  schedule.activationDate AS activationDate,
                  365 AS "KBSTATE",
                  assetValuationInp.narrative AS invoiceId,
                  (CASE
                      WHEN assetValuationInp.valuation IS NULL THEN 0
                      ELSE assetValuationInp.valuation
                   END)
                     AS invoiceAmount,
                  assetValuationInp.valueDate AS invoiceDate,
                  assetUsageHistory.readingValue AS kilometers,
                  installSchema.DETAIL AS installmentSchemaId,
                  installSchemaVer.DETAIL AS installmentSchemaVersion,
                  interestSchema.DETAIL AS interestSchemaId,
                  interestSchemaVer.DETAIL AS interestSchemaVersion,
                  SUBSTR (asset.serialNumber, -6) AS vinLast6,
                  stockId.DETAIL AS stockId,
                  deliveryLink.DETAIL AS deliveryLink,
                  TO_DATE (
                     CAST (
                        CASE
                           WHEN (deliveryDate.DATEFIELD = 0) THEN NULL
                           ELSE deliveryDate.DATEFIELD
                        END AS NVARCHAR2 (8)),
                     'yyyymmdd')
                     AS deliveryDate,
                  CASE
                     WHEN UPPER (CONCAT (submitter.thirdPartyNumber, '')) IN
                             ('<NONE>', '', 'NULL')
                     THEN
                        0
                     ELSE
                        TO_NUMBER (submitter.thirdPartyNumber)
                  END
                     AS submitterId,
                  agreementAlert.dunningBlock AS dunningBlock,
                  odsInvoicingCompany.code AS "brandId",
                  odsInvoicingCompany.name AS "brand",
                  agrCompany.id AS "mandantId",
                  modelHSN.DETAIL AS hsn,
                  modelTSN.DETAIL AS tsn,
                  briefNumber.DETAIL AS documentNr,
                  schedule.MATURITYDATE AS finalDate
             FROM ALFAODS.OdsScheduleMain schedule
                  INNER JOIN ALFAODS.OdsAgreement agreement
                     ON schedule.agreementId = agreement.id
                        AND agreement.productCode = 'WHS'
                  INNER JOIN ALFAODS.OdsAsset asset
                     ON asset.scheduleId = schedule.id
                  INNER JOIN ALFAODS.OdsThirdParty thirdPartyDealer
                     ON schedule.invCusId = thirdPartyDealer.id
                  INNER JOIN ALFAODS.OdsThirdParty submitter
                     ON schedule.dealerid = submitter.id
                  JOIN ALFAODS.OdsTmpSystemDate dates
                     ON 1 = 1
                  LEFT JOIN ALFAODS.OdsThirdParty supplier
                     ON supplier.id = asset.supplierId
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS installSchema
                     ON installSchema.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND installSchema.informationType = 'WINSS'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS interestSchema
                     ON interestSchema.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND interestSchema.informationType = 'WINTS'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS application
                     ON application.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND application.informationType = 'WAPID'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS productId1
                     ON productId1.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND productId1.informationType = 'WPID1'
                        AND (:2 IS NULL
                             OR productId1.DETAIL = NVL (:3, productId1.DETAIL))
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS productId2
                     ON productId2.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND productId2.informationType = 'WPID2'
                        AND (:4 IS NULL
                             OR productId2.DETAIL = NVL (:5, productId2.DETAIL))
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS productId3
                     ON productId3.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND productId3.informationType = 'WPID3'
                        AND (:6 IS NULL
                             OR productId3.DETAIL = NVL (:7, productId3.DETAIL))
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS productId4
                     ON productId4.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND productId4.informationType = 'WPID4'
                        AND (:8 IS NULL
                             OR productId4.DETAIL = NVL (:9, productId4.DETAIL))
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS stockID
                     ON stockID.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND stockID.informationType = 'WSTID'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS proposalStatus
                     ON proposalStatus.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND proposalStatus.informationType = 'WPRST'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS creationDate
                     ON creationDate.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND creationDate.informationType = 'WCRDT'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS installSchemaVer
                     ON installSchemaVer.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND installSchemaVer.informationType = 'WINSV'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS interestSchemaVer
                     ON interestSchemaVer.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND interestSchemaVer.informationType = 'WINTV'
                  --           LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS cancellationDate      ON cancellationDate.alfaScheduleIdentifier = schedule.alfaScheduleIdentifier AND cancellationDate.informationType = 'WCD'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS deliveryLink
                     ON deliveryLink.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND deliveryLink.informationType = 'WDLNK'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS productId
                     ON productId.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND productId.informationType = 'WPRID'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS deliveryDate
                     ON deliveryDate.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND deliveryDate.informationType = 'WDELD'
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS netting
                     ON netting.alfaScheduleIdentifier =
                           schedule.alfaScheduleIdentifier
                        AND netting.informationType = 'WNETT'
                  LEFT JOIN ALFAODS.OdsAssetValuation assetValuationInp
                     ON (    assetValuationInp.assetId = asset.id
                         AND assetValuationInp.valueTypeCode = 'INP'
                         AND assetValuationInp.isCurrentForTypeAndSource = 1)
                  LEFT JOIN ALFAODS.OdsAssetUsageHistory assetUsageHistory
                     ON asset.assetidentifier = assetUsageHistory.assetId
                  LEFT JOIN ALFAODS.OdsAgreementAlert agreementAlert
                     ON agreementAlert.agreementId = agreement.id
                  LEFT JOIN ALFAODS.OdsCompany odsInvoicingCompany
                     ON odsInvoicingCompany.id = schedule.invCompanyId
                  LEFT JOIN ALFAODS.OdsCompany agrCompany
                     ON agrCompany.id = schedule.agrCompanyId
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOASSET modelHSN
                     ON     modelHSN.assetIdentifier = asset.assetidentifier
                        AND modelHSN.informationType = u'MANUN'
                        AND modelHSN.DETAIL = NVL (:10, modelHSN.DETAIL)
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOASSET modelTSN
                     ON     modelTSN.assetIdentifier = asset.assetidentifier
                        AND modelTSN.informationType = u'MODC'
                        AND modelTSN.DETAIL = NVL (:11, modelTSN.DETAIL)
                  LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOASSET briefNumber
                     ON     briefNumber.assetIdentifier = asset.assetidentifier
                        AND briefNumber.informationType = u'BNR'
                        AND briefNumber.DETAIL = NVL (:12, briefNumber.DETAIL)
            WHERE (:13 IS NULL
                   OR SUBSTR (asset.serialNumber, -6) IN
                         (    SELECT REGEXP_SUBSTR (NVL (:14, ''),
                                                    '[^,]+',
                                                    1,
                                                    LEVEL)
                                FROM DUAL
                          CONNECT BY REGEXP_SUBSTR (NVL (:15, ''),
                                                    '[^,]+',
                                                    1,
                                                    LEVEL)
                                        IS NOT NULL))
                  AND (:16 IS NULL
                       OR asset.serialNumber IN
                             (    SELECT REGEXP_SUBSTR (NVL (:17, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:18, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
                  AND (:19 IS NULL
                       OR thirdPartyDealer.thirdPartyNumber IN
                             (    SELECT REGEXP_SUBSTR (NVL (:20, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:21, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
                  AND (:22 IS NULL
                       OR supplier.thirdPartyNumber IN
                             (    SELECT REGEXP_SUBSTR (NVL (:23, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:24, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
                  AND (:25 IS NULL
                       OR thirdPartyDealer.thirdPartyNumber IN
                             (SELECT thirdpartynumber FROM extDealer))
                  AND (:26 IS NULL
                       OR UPPER (proposalStatus.DETAIL) IN
                             (    SELECT REGEXP_SUBSTR (NVL (:27, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:28, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
                  AND (:29 IS NULL
                       OR agreement.agreementNumber IN
                             (    SELECT REGEXP_SUBSTR (NVL (:30, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:31, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
                  AND (:32 IS NULL OR asset.modelName LIKE '%' || :33 || '%')
                  AND (   :34 IS NULL
                       OR assetValuationInp.narrative = :35
                       OR stockId.DETAIL = :36)
                  AND (:37 IS NULL
                       OR productId1.DETAIL = NVL (:38, productId1.DETAIL))
                  AND (:39 IS NULL
                       OR productId2.DETAIL = NVL (:40, productId2.DETAIL))
                  AND (:41 IS NULL
                       OR productId3.DETAIL = NVL (:42, productId3.DETAIL))
                  AND (:43 IS NULL
                       OR productId4.DETAIL = NVL (:44, productId4.DETAIL))
                  AND ( (:45 IS NULL)
                       OR assetValuationInp.valueDate >=
                             TO_DATE (:46, 'yyyy-MM-dd'))
                  AND ( (:47 IS NULL)
                       OR assetValuationInp.valueDate <=
                             TO_DATE (:48, 'yyyy-MM-dd'))
                  AND ( (:49 IS NULL)
                       OR schedule.activationDate >=
                             TO_DATE (:50, 'yyyy-MM-dd'))
                  AND ( (:51 IS NULL)
                       OR schedule.activationDate <=
                             TO_DATE (:52, 'yyyy-MM-dd'))
                  AND (:53 IS NULL
                       OR modelHSN.DETAIL = NVL (:54, modelHSN.DETAIL))
                  AND (:55 IS NULL
                       OR modelTSN.DETAIL = NVL (:56, modelTSN.DETAIL))
                  AND (:57 IS NULL
                       OR briefNumber.DETAIL = NVL (:58, briefNumber.DETAIL))
                  AND (:59 IS NULL
                       OR (TO_DATE (:60, 'yyyy-MM-dd') <= schedule.MATURITYDATE))
                  AND (:61 IS NULL
                       OR (schedule.SCHEDULESTATUS = 'Live (Primary)'
                           AND TO_DATE (:62, 'yyyy-MM-dd') >=
                                  schedule.MATURITYDATE
                           OR schedule.SCHEDULESTATUS = 'Terminated'
                              AND ADD_MONTHS (
                                     TRUNC (TO_DATE (:63, 'yyyy-MM-dd'),
                                            'MONTH'),
                                     2) >= schedule.MATURITYDATE))
         ORDER BY CASE
                     WHEN UPPER (:64) = 'LOANID' AND UPPER (:65) = 'ASC'
                     THEN
                        agreement.agreementNumber
                  END ASC,
                  CASE
                     WHEN UPPER (:66) = 'LOANID' AND UPPER (:67) <> 'ASC'
                     THEN
                        agreement.agreementNumber
                  END DESC,
                  CASE
                     WHEN UPPER (:68) <> 'LOANID' AND UPPER (:69) = 'ASC'
                     THEN
                        thirdPartyDealer.thirdPartyNumber
                  END ASC,
                  CASE
                     WHEN UPPER (:70) <> 'LOANID' AND UPPER (:71) <> 'ASC'
                     THEN
                        thirdPartyDealer.thirdPartyNumber
                  END DESC       
 OFFSET :72  ROWS FETCH NEXT :73  ROWS ONLY
),
Selection2 
AS (
SELECT
LOANID,
PROPOSALSTATUSCODE,
SCHEDULESTATUS,
"supplierGPNr",
LOANSTATE,
PRODUCTID1,
PRODUCTID2,
PRODUCTID3,
PRODUCTID4,
WMPRODUCTID,
VIN,
MODELNAME,
LOANAMOUNT,
BALANCE,
DEALERGPNR,
DEALERNAMESHORT,
CREATIONDATE,
ACTIVATIONDATE,
CASE WHEN (scheduleStatus = 'Live (Primary)') THEN finalDate
     ELSE (SELECT max(receivable.dueDate)
                   FROM ALFAODS.OdsReceivable receivable
                        INNER JOIN ALFAODS.OdsChargeType chargeType on receivable.recvChargeTypeId = chargeType.id AND chargeType.code = 2
                   WHERE receivable.scheduleId = schedule_id) END AS CANCELLATIONDATE,
KBSTATE,
DOCUMENTNR,
documentStateLoan.DETAIL                   as documentStateLoan,
loanDocumentLocation.DETAIL                as documentLocation,
TO_DATE(CAST(CASE WHEN (loanDocumentDate.DATEFIELD = 0) THEN null
                  ELSE loanDocumentDate.DATEFIELD  END AS NVARCHAR2(8)),  'yyyymmdd')   as documentStatusDate,
typeId.DETAIL             as schwackeCodes,
assetValuation.valuation  as schwackeValue,
INVOICEID,
INVOICEAMOUNT,
INVOICEDATE,
KILOMETERS,
INSTALLMENTSCHEMAID,
0 AS INSTALLMENTSCHEMAVERSION,
INTERESTSCHEMAID,
0 AS INTERESTSCHEMAVERSION,
VINLAST6,
HSN,
TSN,
STOCKID,
NULL AS DELIVERYLINK,
DELIVERYDATE,
SUBMITTERID,
docRepositary.DETAIL as docRepositaryId,
DUNNINGBLOCK,
"brandId",
"brand",
"mandantId",
NULL AS vatDeduction,
NULL AS schwackeDeduction,
NULL AS ignoreRetention,
500 AS TOTAL
FROM selection sel
         LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS documentStateLoan ON documentStateLoan.alfaScheduleIdentifier = sel.scheduleId AND documentStateLoan.informationType = 'WDCLS' AND documentStateLoan.DETAIL= NVL(:74 , documentStateLoan.DETAIL)
         LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS loanDocumentDate  ON loanDocumentDate.alfaScheduleIdentifier = sel.scheduleId AND loanDocumentDate.informationType = 'WCRDT'
         LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS loanDocumentLocation ON loanDocumentLocation.alfaScheduleIdentifier = sel.scheduleId AND loanDocumentLocation.informationType = 'WLDLC' AND loanDocumentLocation.DETAIL = NVL(:75 , loanDocumentLocation.DETAIL)
         LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOS docRepositary ON docRepositary.alfaScheduleIdentifier = sel.scheduleId AND docRepositary.informationType = 'WDRID'
         LEFT JOIN ALFAODS.ODSTMPCURRENTMISCINFOASSET typeId ON typeId.assetIdentifier = sel.assetId AND typeId.informationType = u'WTYID'
         LEFT JOIN ALFAODS.OdsAssetValuation assetValuation on (
                   assetValuation.assetId = sel.assetId
                   AND assetValuation.valueTypeCode = 'TTV'
                   AND assetValuation.isCurrentForTypeAndSource = 1)
WHERE
        (:76  IS NULL OR documentStateLoan.DETAIL = NVL(:77 ,documentStateLoan.DETAIL))
      AND
        (:78  IS NULL OR loanDocumentLocation.DETAIL = NVL(:79 ,loanDocumentLocation.DETAIL))
)
SELECT selection2.CANCELLATIONDATE as FINALDATE, selection2.* FROM selection2
where
scheduleStatus = 'Live (Primary)'
or (scheduleStatus  = 'Terminated' and cancellationdate BETWEEN TO_DATE(NVL(:80 , '1900-01-01'), 'yyyy-MM-dd') AND TO_DATE(NVL(:81 ,'9999-12-31'), 'yyyy-MM-dd'))

【问题讨论】:

    标签: oracle oracle12c materialized-views


    【解决方案1】:

    所以,首先,回答您的问题 - 无法使用绑定变量提前实现这一点。您需要在没有任何绑定变量条件的情况下实现查询,并且在具体化视图中提供足够的数据来评估绑定变量。

    也就是说,

    CREATE MATERIALIZED VIEW mat1 AS
    SELECT ... all the data, no bind variables ...
    

    在运行时:

    SELECT ... FROM mat1 WHERE ... bind variable conditions ...
    

    您的查询有很多连接。 refresh fast on commit 物化视图可能很困难。如果您有 Oracle 12.2,请查看物化视图的 ENABLE ON QUERY COMPUTATION 特性。基本上,您会定期刷新(可能每天或每隔几个小时,这取决于数据的(不稳定)程度以及查询运行所需的时间),但 Oracle 仍然通过补充(稍微陈旧的)来保证实时、新鲜的结果) 物化视图数据与物化视图日志中的数据。

    话虽如此,我还不会进入物化视图。相反,我会根据不为空的条件切换到动态构建和执行查询。实际上,您对 Oracle 优化器施加了很大的压力,它基本上只有两个工具可以在这里做得很好:“NVL-OR 扩展”和绑定感知游标。

    这两种方法都为 Oracle 提供了一种方法,可以根据为绑定变量提供的值来制定不同的执行计划。它们是很好的功能,但我只是认为您的查询可能对他们来说有点让我完全信任。如果存在已证明的问题,则尤其如此。

    如果您动态构建和执行查询,这很痛苦,诚然,您可以通过提交一组更小、更集中、更易于优化的查询来简化 CBO 的工作。

    当我说动态构建查询时,我的意思是这样的:

    IF p_param_3rd_party_list IS NULL THEN
      l_sql := l_sql || ' AND NVL(:23,''XXX'') IS NOT NULL';
      l_sql := l_sql || ' AND NVL(:24,''XXX'') IS NOT NULL';
    ELSE 
      -- I'm not bothering to convert all the single quotes to double quotes.  Syntax won't 
      -- work, but you get the idea...
      l_sql := l_sql || ' AND (supplier.thirdPartyNumber IN
                             (    SELECT REGEXP_SUBSTR (NVL (:23, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                    FROM DUAL
                              CONNECT BY REGEXP_SUBSTR (NVL (:24, ''),
                                                        '[^,]+',
                                                        1,
                                                        LEVEL)
                                            IS NOT NULL))
    END IF;
    
    EXECUTE IMMEDIATE l_sql USING ... all your bind variables
    

    出于可伸缩性原因,您仍然使用绑定变量(如上所示)至关重要,即使您正在动态构建查询。

    当绑定变量为 NULL 时添加的虚拟条件的要点是,最终查询具有相同顺序的绑定变量列表,而不管实际给出了哪些参数。这样,您可以使用一个EXECUTE IMMEDIATE...USING... 命令执行它。否则,这是一个巨大的痛苦。

    【讨论】:

    • 谢谢@Matthew。我可以使用提示/*+ bind_aware */ 使查询绑定感知,否则它会被忽略?
    • 我无法以这种方式转换查询,它是由使用嵌入在请求中的查询的休息服务触发的。
    • 您是说您根本无法更改查询吗?你打算如何使用物化视图?查询重写?或者您是说请求必须是SELECT 语句,而不是过程调用。如果是后者,您可以使用流水线函数进行动态执行,并从中获得服务SELECT
    • 也许我没有以正确的方式解释自己。我可以更改查询,但它必须是一个选择语句。管道功能可能是一种选择,但它使事情变得复杂而不是使它变得更容易。您如何看待使用 bind_aware 提示?你认为这会迫使 CBO 根据通知的不同绑定变量集计算不同版本的计划吗?
    • 提示永远不会“强迫”CBO 做任何事情。你可以试试看。我不会太乐观。
    猜你喜欢
    • 2022-11-24
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2022-11-12
    • 2011-01-04
    相关资源
    最近更新 更多