浅谈使用JDBC Update时不能使用索引的原因
创始人
2024-04-15 02:31:28
0

表DYN_DAYAHEAD_BID按时间data_time分区,有5个分区,建立了一个本地分区索引index ind_dyn_daybid_store,索引列是data_time, tag_phy, tag_app,version四个字段。

一直以来,觉得JDBC Update修改数据时特别慢(根据业务逻辑,往往是一次update 481条记录)。今天trace了应用程序的执行计划(应用程序通过jdbc访问数据库,数据库版本为oracle 9.2.0.1)。通过jdbc的执行计划(trace文件)如下:

  1. select Data_Time,Tag_Phy,Tag_App,Value_0,Value_1,Value_2,Value_3,Value_4,  
  2.   Value_5,Value_6,Value_7,Value_8,Value_9,Version   
  3. from  
  4. DYN_DAYAHEAD_BID where Tag_Phy = :1 and version = :2 and Data_Time > :3 and   
  5.   Data_Time <= :4+1 and Tag_App in ('5TMS01DBS07','5TMS01DBS08','5TMS01DBS09',  
  6.   '5TMS01DBS10','5TMS01DBS11','5TMS01DBS12')  
  7.  
  8.  
  9. call     count       cpu    elapsed       disk      query    current        rows  
  10. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  11. Parse        1      0.00       0.00          0          0          0           0  
  12. Execute      1      0.00       0.00          0          0          0           0  
  13. Fetch       49      0.04       0.02          0        609          0         481  
  14. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  15. total       51      0.04       0.02          0        609          0         481  
  16.  
  17. Misses in library cache during parse: 1  
  18. Optimizer goal: CHOOSE  
  19. Parsing user id: 62    
  20.  
  21. Rows     Row Source Operation  
  22. -------  ---------------------------------------------------  
  23.     481  PARTITION RANGE ITERATOR PARTITION: 1 KEY   
  24.     481   TABLE ACCESS BY LOCAL INDEX ROWID DYN_DAYAHEAD_BID PARTITION: 1 KEY   
  25.     481    INDEX RANGE SCAN IND_DYN_DAYBID_STORE PARTITION: 1 KEY (object id 30391)  
  26.  
  27. ....  
  28. update DYN_DAYAHEAD_BID set Value_0 = :1 , Value_1 = :2 , Value_2 = :3 ,   
  29.   Value_3 = :4 , Value_4 = :5 , Value_5 = :6 , Value_6 = :7 , Value_7 = :8 ,   
  30.   Value_8 = :9 , Value_9 = :10   
  31. where  
  32. Data_Time= :11 and Tag_Phy= :12 and Tag_App= :13 and Version= :14  
  33.  
  34.  
  35. call     count       cpu    elapsed       disk      query    current        rows  
  36. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  37. Parse      481      0.02       0.03          0          0          0           0  
  38. Execute    481     12.85      13.23        346     277537        500         481  
  39. Fetch        0      0.00       0.00          0          0          0           0  
  40. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  41. total      962     12.87      13.26        346     277537        500         481  
  42.  
  43. Misses in library cache during parse: 1  
  44. Optimizer goal: CHOOSE  
  45. Parsing user id: 62    
  46.  
  47. Rows     Row Source Operation  
  48. -------  ---------------------------------------------------  
  49.       0  UPDATE    
  50.       1   PARTITION RANGE ALL PARTITION: 1 5   
  51.       1    TABLE ACCESS FULL DYN_DAYAHEAD_BID PARTITION: 1 5  

显然,查询时是JDBC Update用到了索引,而修改时JDBC Update没有使用索引,但我在sqlplus下执行类似的语句,则明显的使用了索引:

  1. SQL> update DYN_DAYAHEAD_BID set value_0=111 
  2.      where data_time=to_date('2006-04-14 0:15:00','yyyy-mm-dd hh24:mi:ss')  
  3.      and tag_phy='303101120211' and tag_app='5TMS01DBS07' and version=1 
  4. SQL> / 

JDBC Update已更新 1 行。

  1. Execution Plan  
  2. ----------------------------------------------------------  
  3.    0      UPDATE STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=51)  
  4.    1    0   UPDATE OF 'DYN_DAYAHEAD_BID'  
  5.    2    1     INDEX (UNIQUE SCAN) OF 'IND_DYN_DAYBID_STORE' (UNIQUE) (  
  6.           Cost=1 Card=1 Bytes=51

然后,我对程序中的sql语句增加了hint,强制使用索引,然后程序的执行计划如下:

  1. update  /*+ INDEX(dyn_dayahead_bid ind_dyn_daybid_store) */ DYN_DAYAHEAD_BID   
  2.   set Value_0 = :1 , Value_1 = :2 , Value_2 = :3 , Value_3 = :4 , Value_4 =   
  3.   :5 , Value_5 = :6 , Value_6 = :7 , Value_7 = :8 , Value_8 = :9 , Value_9 =   
  4.   :10   
  5. where  
  6. Data_Time= :11 and Tag_Phy= :12 and Tag_App= :13 and Version= :14  
  7.  
  8.  
  9. call     count       cpu    elapsed       disk      query    current        rows  
  10. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  11. Parse      481      0.04       0.02          0          0          0           0  
  12. Execute    481     11.37      11.48          0     247234        502         481  
  13. Fetch        0      0.00       0.00          0          0          0           0  
  14. ------- ------  -------- ---------- ---------- ---------- ----------  ----------  
  15. total      962     11.41      11.50          0     247234        502         481  
  16.  
  17. Misses in library cache during parse: 0  
  18. Optimizer goal: CHOOSE  
  19. Parsing user id: 62    
  20.  
  21. Rows     Row Source Operation  
  22. -------  ---------------------------------------------------  
  23.       0  UPDATE    
  24.       1   PARTITION RANGE ALL PARTITION: 1 5   
  25.       1    INDEX FULL SCAN IND_DYN_DAYBID_STORE PARTITION: 1 5 (object id 30391) 

现在看起来是JDBC Update使用了索引,但好像对索引进行全表扫描,跟查询和在sqlplus下使用范围扫描不一样。

由于现在表中的数据比较少,就已经很慢了,以后更加不可能接受,请教各位,为什么在程序中没有正确的使用索引,有什么解决的方法吗?

谢谢大家!

【编辑推荐】

  1. 使用JDBC的五个精华功能
  2. Tomcat5+MySQL JDBC连接池配置
  3. 在Weblogic中实现JDBC的功能
  4. 详解JDBC与Hibernate区别
  5. JDBC连接MySQL数据库关键四步
  6. 详解JDBC驱动的四种类型

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...