cyt

前几天客户投诉我们提供的一个访问Oracle的程序,说运行太慢了,半天都没有处理完数据。
客户数据也就几十万条,也不是什么海量数据,究竟什么原因呢。而且奇怪的是我们提供的其它类似的程序访问同一张数据表却没有任何的问题。
经过多次反复写测试程序,尝试各种的条件,最后发现原来是其中一条update语句执行很慢,要2秒钟才更新一条。而这条update语句的where部分有两个条件,一个是整数的比较条件,一个是日期的比较条件。当然很容易就可以通过测试排除了整数条件导致慢的可能性。剩下的原因就是日期比较条件导致慢了。
说得也奇怪,日期条件是通过param的方式传入参数的,执行很慢。但测试的时候如果把日期条件展开,把日期条件变成SQL的一部分,那就执行很快了。先不论为什么这么奇怪,要知道Oracle SQL语句的日期条件不是一般的麻烦,都要经过TO_DATE/TO_CHAR糊弄来糊弄去,SQL语句跟其他的数据库不一样,程序就失去通用性了。一定是自己调用OCI的时候犯了什么糊涂错误了。
最后还是发现有一个不妥当的地方:数据库字段类型是DATE,而我用OCI绑定param的时候,用的却是SQLT_TIMESTAMP。原因是我想偷懒,希望用OraDateStruct就解决OCI的日期类型。于是我尝试用回SQLT_DAT,自己“笨笨的”把时间转换为OCI所能辨认的7个byte的数组,然后运行程序。速度太快了,一下子就执行完了。
其实不明白的是,Oracle发现类型不匹配,要不就报错;要不就把条件变为相容的数据进行查询。但是现在从现象看来,Oracle像是把所有保存的数据逐个转换成为与条件相容的类型进行判断,而不是转换条件的类型。所以每次update都变成了遍历所有的数据。难道是存在DBA可以调整的优化策略??不明白,不明白……

posted on 2007-03-30 00:00 cyt 阅读(2241) 评论(5)  编辑 收藏 引用 所属分类: Work
Comments
  • # re: 补充一个OCI的问题
    你好!请教个问题
    Posted @ 2007-06-15 09:04
    你好!
    你好, 看了你的一些文章感觉你好厉害得说!
    我不是专门研究程序的人,
    可现在我有点小困难,希望你帮忙解决 以下
    你的一片文章里说:
    singalslot.h里面就定义:
    #define TEMPLATE_ARGS typename A1
    #define FUNC_ARGS A1 a1
    #define SLOTBASENAME slot1base
    #include "signalslot.imp"

    #define TEMPLATE_ARGS typename A1,typename A2
    #define FUNC_ARGS A1 a1, A2 a2
    #define SLOTBASENAME slot2base
    #include "signalslot.imp"
    ……
    我运行程序时候就缺少singalslot.h这个文件,一直在寻找singalslot.h这个头文件,你能帮忙写给我吗?
    我的QQ346183499,全天再线
    谢谢了!
      回复  更多评论   
  • # re: 补充一个OCI的问题
    cyt
    Posted @ 2007-09-17 13:01
    Sorry长久没有上来,所以没有看到你的问题。
    这个signalslot.h是以前我自己研究练习写的,没有发布过,现在一下子也找不到在哪里。估计你的情况是需要的是一个第三方公开的那种类库吧。估计这几个对你有帮助:
    http://www.codeproject.com/cpp/ElmueSignalsandSlots.asp?df=100&forumid=38296&exp=0&select=1762527
    http://sigslot.sourceforge.net/
      回复  更多评论   
  • # re: 补充一个OCI的问题
    hongtium
    Posted @ 2007-10-10 13:52
    这个问题不是OCI才有的,Java的JDBC一样。
    原因在于,用接口方式写入的绑定变量,形如 "where xdate<? ", OCI或者JDBC调用产生的内部执行计划都会把变量自动变成"where xdate<to_timestamp(?) " 形式。所以,如果xdate定义为date类型,则因为精度不匹配,oracle执行计划将放弃对xdate的索引。
    解决就是把xdate定义成oracle的timestamp类型,或者把sql改成xdate<to_date(...)形式。
    至于oracle因为日期精度不匹配就不使用索引,可能是oracle的“过度安全”考虑。 原因大概是oracle的date/timestamp存储结构不同。
      回复  更多评论   
  • # re: 补充一个OCI的问题
    canyon
    Posted @ 2008-06-14 13:34
    请教一个问题, 我使用SQLT_DAT绑定变量后使用7个字节的unsigned char将日期记入数据的DATE类型字段, 之后使用select *查询可以看到日志,但是使用select to_char将其转换成字符串确传回的是0000-0-0

    不知道为什么,还望赐教  回复  更多评论   
  • # re: 补充一个OCI的问题
    兄弟帮忙看看,多谢
    Posted @ 2013-05-27 10:51
    兄弟,请教下occi如何绑定参数为date类型,我这边代码如下:

    sql语句是:
    std::string sql = "INSERT INTO tbl_test(myid, myvc,myblob,mydt,mycblob)
    VALUES(111,'abc','blob',:a,'abc')";
    m_Command->setSql(sql);

    bool result = false;
    oracle::occi::Date d(m_pOwner->GetOracleEnvironment());
    d.setDate(Data.wYear, Data.wMonth, Data.wDay, Data.wHour, Data.wMinute, Data.wSecond);
    m_Command->setDate(index, d);

    然后执行这条语句的时候就报错:
    ORA-01465: invalid hex number

    我的qq:2212099931  回复  更多评论   

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理