V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kojp
V2EX  ›  Oracle

好久没发帖提问了。问个ORACLE的性能问题(菜鸟级。。)

  •  
  •   kojp · 2012-11-28 17:44:01 +08:00 · 3547 次点击
    这是一个创建于 4410 天前的主题,其中的信息可能已经有所发展或是发生改变。
    两个表大概60w行的数据吧。
    其中一个做了索引,一个没做。
    一个简单的关联查询。
    耗时不有点不正常(相比以前)


    查询语句是这样的。
    table1 中有c1,c2 等字段
    table2中有id,name等字段

    select c1 from table1 t1,table2 t2 where t2.id='20121128' and t1.c2=t2.name

    现在的耗时是0.9s 到 10s 不等。
    (超过2s就影响到前台的性能了,现在超过2s的比率大概在30%以上了!)

    服务器配置是 4G 内存,双核,(虽然是很次的服务器,但物理性能上,没看出IO,CPU,内存之类的不够用)。

    系统,是大家都乐意吐糟的SERVER2003

    求解两个问题:
    1,查询时间为什么是随机的,而且相差比较大?对于60W行的数据,正常的速度应该是什么样的?
    2,语句上面,是否有优化的可能性?
    3,给两个表都做索引和只给其中一个表做索引性能上会有区别吗?(其中T2已经有索引)


    谢谢~~~(PS:Oracle太笨重了,以前很少接触。只能是现学现卖)





















    (记得以前不是/new/qna呀!)
    12 条回复    1970-01-01 08:00:00 +08:00
    Muninn
        1
    Muninn  
       2012-11-28 18:22:34 +08:00   ❤️ 1
    这里估计没几个人搞商业数据库。我算是略懂。
    第一你没说索引加哪里了,建议涉及的三个字段分别加单字段索引。第二你需要定期run statistics 。第三建议早点把操作系统换了。你的机配置也就是个oracle的最低配置。。。。
    manoon
        2
    manoon  
       2012-11-28 19:06:49 +08:00
    @Muninn

    谢谢

    索引只做了t2的id
    statics 是什么我地会儿回去查一下.
    话说: 在存储和和系平台不更改, 数据库也不做任何优化的情况下.如果直接上一台32g内存, 6核cpu的话. 能解决问题么?
    Muninn
        3
    Muninn  
       2012-11-28 21:16:42 +08:00
    查询时间不稳定肯定不是增加配置能搞定的
    要是多数时间较长偶尔很快,那是命中缓存了,数据库每次会读整页的数据到内存,并不是整行,所以有可能你要查的刚好在内存。
    要是大部分时间较短偶尔较长,就要查那一瞬间是什么东西把数据库资源抢夺了或者阻塞了。
    其实找个你同事看看执行计划基本就知道怎么了。
    kojp
        4
    kojp  
    OP
       2012-11-28 23:34:29 +08:00
    @Muninn

    大谢!

    关键词------执行计划!

    (同事在外地,机关内网,木有办法远程)

    再提供一些信息。
    1,关于命中缓存。用相关的脚本测试了一下 ,结果是96%以上。
    2,当执行insert 语句的时候,很快!(这可能是废话,因为写入不需要从60W的“茫茫人海”中读东西)
    3, “并发”查询越多的时候,越慢,几乎有80%以上的查询是在10s左右,甚至更长。
    4,我去补课一下“执行计划”(我会告诉你我现在连SYSDBA权限都没有么 :-(。。。)


    PS:
    我有一个弱弱的想法。不知道能成立否。
    这个想法是通过查询run statistics 这个关键词得来的。
    可不可以,做一张类似于虚拟表的东西出来。就是说,我不从60W数据中查询。
    我从最近的1W条数据中查询。

    select c1 from ( select * from table1 where rownum<10000 ) t1,( select * from table1 where rownum<10000 ) t2 where t2.id='20121128' and t1.c2=t2.name 类似于,这个意思。我不知道,我表达清楚了没有。


    再次,深深地鞠躬感谢一下!!!
    即使问题没能解决。也学到了不少知识~~~
    moriz
        5
    moriz  
       2012-11-28 23:41:18 +08:00
    应该就是索引的事, 耗时不同,是因为 t2.id='20121128' 这个条件匹配的记录数不一样
    moriz
        6
    moriz  
       2012-11-28 23:43:14 +08:00
    匹配到记录数多,没加索引的那张表的全表扫描次数就多
    Muninn
        7
    Muninn  
       2012-11-28 23:54:52 +08:00   ❤️ 1
    有的时候你不太了解oracle的解释机制,也有的时候它有些笨。
    在表大量更新后需要做run statistics ,所以频繁更新的表需要用定时任务跑run statistics。
    而执行计划里它如果还没有先取出t2的id的那条记录然后关联的话,你又着急,可以手动解决。
    先写个子查询把t2必要的字段取出来,用id的条件限定。因为id是索引,这是瞬间就出来的。然后再用这个子查询关联t1表,只要关联的条件两边都是索引,也会及其的快。

    关于你说的虚拟表,有现成的方法。 就是oracle的分区表。 你开始没说过你可以限制从某一部分数据查,如果你能有准确找到让数据分布的条件,比如时间,日期,或者id之类的,你可以做分区表。oracle会先用分区条件把搜索范围限制在一个分区中。
    不过几十万大材小用了。应该用不到。
    我们都是记录上亿了才开始用分区表。几千万都不怕的。。。
    所以你几十万要是有问题,而如果表又不是特别宽的话,那很可能是什么很低级的地方出问题了。

    不知道你的表有多宽,所有字段的长度加起来要尽量的压缩,使用varchar2不要用char 如果一行太宽,全部从硬盘中读到内存中的io开销很大。
    kojp
        8
    kojp  
    OP
       2012-11-29 00:18:15 +08:00
    @Muninn
    @moriz

    谢谢,有你们这两条回复。我心里就有几分把握了。哈哈~~~

    先把索引搞起!
    然后写个crontab
    再找其它的,小BUG。

    ps:关于你说的字查询,是不是要更改查询语句了?
    改成

    select c1 from table1 t1 where t1.c2=(select t2.name from table2 t2 where t2.id='20121128' ))

    这样咩(感觉有点不通顺。。。)
    Muninn
        9
    Muninn  
       2012-11-29 00:26:53 +08:00
    select t1.c1 from table1 t1,(select t2.name as name from table2 t2 where t2.id='20121128' ) t3 where t1.c2=t3.name 这是oracle语法
    select t1.c1 from table t1
    join (select t2.name as name from table2 t2 where t2.id='20121128' ) t3
    on t1.c2=t3.name 这是标准SQL
    select t1.c1 from table1 t1 where t1.c2 in (select t2.name as name from table2 t2 where t2.id='20121128' ) in不会走索引 但是括号里的结果集要是很小也不慢
    coldear
        10
    coldear  
       2012-11-29 00:34:35 +08:00
    先看execution plan。。
    如果你的c2和name没有加index,这个查询效率肯定高不了,
    select c1有可能做一次lkey ookup,这个也很影响效率
    coldear
        11
    coldear  
       2012-11-29 00:35:21 +08:00
    *key lookup
    manoon
        12
    manoon  
       2012-11-29 15:32:36 +08:00
    结帖! ! ! 谢谢各位!
    已经搞定. . . 就是索引的问题
    现在的查询测试都在1s 以内.
    .( 我会告诉你们原来这两个表连主键都没有么)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1632 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:50 · PVG 00:50 · LAX 08:50 · JFK 11:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.