首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按条款订购的履约问题

按条款订购的履约问题
EN

Stack Overflow用户
提问于 2012-02-25 05:46:07
回答 3查看 8.2K关注 0票数 3

下面的查询在执行后从100000000返回20000条记录。

代码语言:javascript
复制
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:

代码语言:javascript
复制
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是一个月的范围分区表。

EN

回答 3

Stack Overflow用户

发布于 2012-02-25 12:41:50

让我们从免责声明开始:如果您不删除该order by或开始使用临时表,那么的执行时间就不会减少到4s。第二个免责声明:我犯了一个很大的错误,我现在正在改正;我花了很长时间才意识到这一点。谢谢你亚历克斯普尔

我的观点(我总是有几点)。

  1. 在评论中,特别是由DimitryB提出了一些非常有效的观点。如果一次只显示10条记录,那么20,000行等于2,000页。没有人会费心去看所有这些信息。您可以非常安全地将返回的记录数量减少到500条,如果不是100条或200条的话。
  2. craigmj的回答也提出了一个同样有效的观点,尽管我想对其进行显着的扩展。通过不索引、everything、、where子句、和,您中的所有内容都可以保证是table access by index rowid。这意味着,对于从最内部的select返回的每一行,从索引中提取的行也会重新访问表。不过,我认识到,这将是你当前桌子上的一个非常大的指数。
  3. 你似乎多做了一个比需要的更多的选择。您可以在主select中按顺序订货。您还在别名之上的两个级别引用别名a。虽然这可能不会引起任何问题,但这有点让人困惑,您将以列rnum结束两次。
  4. 100米行将到达光谱的最大端。任何人浏览所有这些信息的可能性是不太可能的,而且从您的评论中可以看出,它们并不都在报告中使用。虽然表是分区的,这将有很大帮助,但Oracle仍然需要确定要使用哪个分区。
  5. 从第5点开始,您已经按月对表进行了分区,但只选择了3天的数据。我同意这是明智的,但如果您只需要一个月的数据最多可以方便地访问,它可能值得一天分区为一个较小的表?您提到了2,300份报告使用了这个表;如果它们都花了5分钟,那么就应该考虑一些极端的方法,比如这种方法。
  6. 这有点可悲,但url是否需要1024个字符呢?

将这些要点有效地归结为我的主要建议;缩小了表的大小。然后,将尽一切可能删除Oracle需要做的任何额外工作;甚至将大部分表转换为索引。

因此,这些步骤将是:

  • 将所有大于一个月的数据归档到一个单独的表中。每天都要这样做。
  • 按日划分较小的表。
  • 如果您只需要几天的数据,肯定值得考虑创建一个物化视图,订单已经就位了。
  • 在这个新的、较小的表上使用“最优”索引;因此,您根本不必真正地触摸该表。我把倒逗号放在最优的位置,因为这一直是公开讨论的,我的建议可能有点不正确,但通常是,列,where, group by, order by and select clauses中的列,按顺序排列,和,顺序是降低选择性。这将使您的索引类似于"5mintime", username, category, domain, appid, url, bytes
  • 如果可能的话,使索引唯一。
  • 确保您的查询没有做任何它不需要做的事情来减少工作负载。这包括返回可读的行数。我会这样改写它:
代码语言:javascript
复制
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

希望这一切都有意义;在一天结束时,报表在服务器上完成的工作量以及希望它们运行的速度将决定您想要做什么。

票数 2
EN

Stack Overflow用户

发布于 2012-02-25 05:50:52

您是否尝试将订单从时间更改为5分钟,我确信您在转换值并对其进行排序时没有使用索引。

票数 0
EN

Stack Overflow用户

发布于 2012-02-25 05:51:38

在5分钟内有一个索引,所以按顺序排序,然后在最外层的选择中执行TO_CHAR转换。还可以考虑在WHERE子句中使用的其他字段上建立索引。

另一个想法是查看Oracle正在使用的查询计划,看看它是如何解决问题的。下面是甲骨文的explain planhttp://www.adp-gmbh.ch/ora/explainplan.html的一个很好的教程

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9441649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档