Oracle查询微调

时间:2014-11-17 11:48:27

标签: oracle query-optimization

嗨我有一个大概有大量记录的数据库,400K应该会增长更多。

我有一个查询来从此表中获取数据以向用户显示记录。我的询问如下。

    SELECT  "PC0".PYID   AS "pyID" ,
  "PC0".NAME                 AS "Name" ,
  "PC0".OPPORTUNITYSTAGE     AS "OpportunityStage" ,
  "PC0".PXCREATEOPNAME       AS "pxCreateOpName" ,
  "PC0".PZINSKEY             AS "pzInsKey" ,
  "PC0".OPPORTUNITYSHORTNAME AS "OpportunityShortName" ,
  "PC0".IDTYPE               AS "IDType" ,
  "PC0".IDNO                 AS "IDNo" ,
  "Campaign".PROGRAMNAME     AS "ProgramName" ,
  "Campaign".ENDDATE         AS "EndDate" ,
  "PC0".PRODUCTNAME          AS "ProductName" ,
  "PC0".PRODUCTTYPE          AS "ProductType" ,
  "PC0".OPPORTUNITYSTAGE     AS "OpportunityStage" ,
  "PC0".PXCREATEOPNAME       AS "pxCreateOpName" ,
  "PC0".OPPORTUNITYSOURCE    AS "OpportunitySource" ,
  "PC0".OPPORTUNITYOWNER     AS "OpportunityOwner" ,
  "PC0".IDTYPE
  ||"PC0".IDNO                                                          AS "pyTextValue(1)" ,
  "PC0".REMINDERDATE                                                    AS "ReminderDate" ,
  "PC0".STAGELASTCHANGED                                                AS "StageLastChanged" ,
  ROUND((CAST(SYSDATE AS DATE) - CAST("PC0".STAGELASTCHANGED AS DATE))) AS "pyIntegerValue(1)" ,
  (
  CASE
    WHEN ROUND((CAST(SYSDATE AS DATE) - CAST("PC0".REMINDERDATE AS DATE))) > 0
    THEN 1
    WHEN ROUND((CAST(SYSDATE AS DATE) - CAST("PC0".STAGELASTCHANGED AS DATE))) > 7
    THEN 2
    ELSE 3
  END)                                                              AS "pyIntegerValue(2)" ,
  "PC0".PXCREATEDATETIME                                            AS "pxCreateDateTime" ,
  "PC0".CAMPAIGNID                                                  AS "CampaignID" ,
  ROUND((CAST(SYSDATE AS DATE) - CAST("PC0".REMINDERDATE AS DATE))) AS "pyIntegerValue(3)"
FROM MYCO_OPPORTUNITY "PC0"
LEFT OUTER JOIN MYCO_CAMPAIGN "Campaign"
ON ( "PC0".CAMPAIGNID = "Campaign".PYID)
ORDER BY 21 ASC,
  22 DESC 

在SQl开发人员中获取前50条记录需要大约13秒。实时我将一次获取近5k的记录。

在我为REMINDERDATE和STAGELASTCHANGED列定义了CAST的功能索引和位图连接索引之后,时间是13秒。

您能否建议我应该如何优化查询。在大型集合上订购可能是一个问题,这对我来说是必须的。 :(

2 个答案:

答案 0 :(得分:0)

确保你有一个索引:" PC0" .CAMPAIGNID和on:" Campaign" .PYID

确保您的SGA设置得足够高。在不了解有关服务器和数据库的大量信息的情况下,除了确保SGA足够大之外,很难提供指导。

答案 1 :(得分:0)

您正在使用"按顺序排列"在计算列上,这意味着Oracle必须为所有400k行计算此值,然后才能对结果进行排序和返回。要确保这是问题测试而不使用order by。

有许多可能的解决方案,但这个例子似乎不是你的实际用例,所以建议对它进行优化几乎没有意义

如果不了解数据,我建议将查询拆分为三个与union相关的部分,并在reminderdate和stagelastchanged上实现索引。

select * from ( [part 1] where reminderdate > sysdate order by pxCreateDateTime ) 
union all
select * from ( [part 2] where reminderdate <= sysdate and stagelastchanged + 7 < sysdate order by pxCreateDateTime ) 
union all
select * from ( [part 3] where reminderdate <= sysdate and stagelastchanged + 7 >= sysdate order by pxCreateDateTime )

然后我希望使用索引来满足1.和2.以及3.全表扫描,这可以通过添加first_rows提示来帮助。