嗨我有一个大概有大量记录的数据库,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秒。
您能否建议我应该如何优化查询。在大型集合上订购可能是一个问题,这对我来说是必须的。 :(
答案 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提示来帮助。