下面的查询在执行后从100000000返回20000条记录。
SELECT *
FROM (SELECT a.*, ROWNUM rnum
FROM (select TIME,url,bytes
FROM (SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS TIME, url, BYTES
FROM available_web_details
WHERE "5mintime" >= TIMESTAMP '2012-02-10 00:00:00'
AND "5mintime" <= TIMESTAMP '2012-02-13 23:59:59'
AND username = 'asha1328874833'
AND CATEGORY = 'None240001'AND domain = '1328874833.vmware.com.'
AND (appid IN ('216.198.204.192id','216.198.207.0id','216.198.211.64id','216.198.211.128id','216.198.212.0id', '216.198.214.128id','216.198.214.192id','216.198.218.0id','216.198.220.192id','216.198.222.0id','216.198.223.32id','216.198.228.128id','216.198.229.128id',.....)))
ORDER BY TIME DESC) a
WHERE ROWNUM <= 10)
WHERE rnum > 0大约需要5分钟才能完成。但是当我删除order子句时,它将在4秒内执行。你能建议我如何提高表演水平吗?
模式的available_web_details:
Name Null Type
------------ ---- --------------
5mintime TIMESTAMP(6)
USERNAME VARCHAR2(64)
HOST NUMBER
SRC_ZONE VARCHAR2(32)
DOMAIN VARCHAR2(512)
DST_ZONE VARCHAR2(32)
CONTENT VARCHAR2(64)
CATEGORY VARCHAR2(64)
URL VARCHAR2(1024)
HITS NUMBER
BYTES NUMBER
APPID VARCHAR2(32)
APPLICATION VARCHAR2(64)
CATEGORYTYPE VARCHAR2(64)
USERGROUP VARCHAR2(384) 我在appid、“5分钟”和本地分区上都有索引。available_web_details是一个月的范围分区表。
发布于 2012-02-25 12:41:50
让我们从免责声明开始:如果您不删除该order by或开始使用临时表,那么的执行时间就不会减少到4s。第二个免责声明:我犯了一个很大的错误,我现在正在改正;我花了很长时间才意识到这一点。谢谢你亚历克斯普尔。
我的观点(我总是有几点)。
where子句、和,您中的所有内容都可以保证是table access by index rowid。这意味着,对于从最内部的select返回的每一行,从索引中提取的行也会重新访问表。不过,我认识到,这将是你当前桌子上的一个非常大的指数。select中按顺序订货。您还在别名之上的两个级别引用别名a。虽然这可能不会引起任何问题,但这有点让人困惑,您将以列rnum结束两次。url是否需要1024个字符呢?将这些要点有效地归结为我的主要建议;缩小了表的大小。然后,将尽一切可能删除Oracle需要做的任何额外工作;甚至将大部分表转换为索引。
因此,这些步骤将是:
where, group by, order by and select clauses中的列,按顺序排列,和,顺序是降低选择性。这将使您的索引类似于"5mintime", username, category, domain, appid, url, bytes。SELECT time, url, bytes, rownum as rnum
FROM ( SELECT time, url, bytes, rowum as rnum
FROM ( SELECT TO_CHAR ("5mintime",'YYYY-MM-DD HH24:MI:SS') AS time
, url
, bytes
FROM available_web_details
WHERE "5mintime" BETWEEN to_timestamp('2012-02-10 00:00:00','YYYY-MM-DD HH24:MI:SS')
AND to_timestamp('2012-02-13 23:59:59','YYYY-MM-DD HH24:MI:SS')
AND username = 'asha1328874833'
AND category = 'None240001'
AND domain = '1328874833.vmware.com.'
AND appid IN ('216.198.204.192id',...)
ORDER BY "5mintime" DESC
)
WHERE rownum <= 10)
WHERE rnum > 0希望这一切都有意义;在一天结束时,报表在服务器上完成的工作量以及希望它们运行的速度将决定您想要做什么。
发布于 2012-02-25 05:50:52
您是否尝试将订单从时间更改为5分钟,我确信您在转换值并对其进行排序时没有使用索引。
发布于 2012-02-25 05:51:38
在5分钟内有一个索引,所以按顺序排序,然后在最外层的选择中执行TO_CHAR转换。还可以考虑在WHERE子句中使用的其他字段上建立索引。
另一个想法是查看Oracle正在使用的查询计划,看看它是如何解决问题的。下面是甲骨文的explain plan:http://www.adp-gmbh.ch/ora/explainplan.html的一个很好的教程
https://stackoverflow.com/questions/9441649
复制相似问题