如何使用绑定变量转换为物化视图查询

How to convert to Materialized view query with bind variables

我的环境:

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

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

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

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

我最后的想法是创建一个在提交时快速刷新的物化视图。数据库上的 DML activity 很少,因此数据并发不会成为问题,我相信不会有那么多的锁定结果。我读到自 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'))

因此,首先要回答您的问题——无法使用绑定变量提前实现这一点。您需要使用 bind-variable 条件中的 none 来具体化查询,并在具体化视图中提供足够的数据来评估绑定变量。

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 仍然保证 real-time,新鲜的结果通过使用实体化视图日志中的数据补充(稍微陈旧的)实体化视图数据。

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

这两者都为 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... 命令执行它。否则,就是一个巨大的痛苦。