1. 程式人生 > >資料型別不一致導致的SQL不走索引

資料型別不一致導致的SQL不走索引

前幾天,同事發來一條SQL,說是更新操作的時候執行的很慢,我看了下,資料量也不是很大。再檢視執行計劃,發現是執行路徑錯誤導致的,可是為什麼會走錯誤的執行路徑呢?統計資訊並沒有太大的問題。在這裡模擬下:

資料準備:

--1.資料準備,表一:
DROP TABLE t_test_1;
create table T_TEST_1
(
  owner          VARCHAR2(30),
  object_name    VARCHAR2(128),
  subobject_name VARCHAR2(30),
  object_id      NUMBER,
  data_object_id NUMBER,
  object_type    VARCHAR2(19),
  created        DATE,
  last_ddl_time  DATE,
  timestamp      VARCHAR2(19),
  status         VARCHAR2(7),
  temporary      VARCHAR2(1),
  generated      VARCHAR2(1),
  secondary      VARCHAR2(1)
);
INSERT INTO T_TEST_1
SELECT * FROM dba_objects;
COMMIT;
UPDATE t_test_1 a SET a.object_type = 'TABLE';
COMMIT;
--2.資料準備,表二:
DROP TABLE t_test_2;
create table T_TEST_2
(
  owner          VARCHAR2(30),
  object_name    VARCHAR2(128),
  subobject_name VARCHAR2(30),
  --這裡資料型別和T_TEST_1中object_id的資料型別不一致
  object_id      VARCHAR2(100),
  data_object_id NUMBER,
  object_type    VARCHAR2(19),
  created        DATE,
  last_ddl_time  DATE,
  timestamp      VARCHAR2(19),
  status         VARCHAR2(7),
  temporary      VARCHAR2(1),
  generated      VARCHAR2(1),
  secondary      VARCHAR2(1),
  --這裡資料型別和T_TEST_1中object_id的資料型別一致
  object_id2      NUMBER
);
INSERT INTO T_TEST_2
SELECT a.*, a.object_id object_id2 FROM dba_objects a;
COMMIT;
SELECT * FROM t_test_1;
CREATE INDEX ind_t_test_2_id1 ON t_test_2(object_id) TABLESPACE TBS_LUBINSU_DATA;
CREATE INDEX ind_t_test_2_id2 ON t_test_2(object_id2) TABLESPACE TBS_LUBINSU_DATA;

T_TEST_2表中的object_id和object_id2兩個欄位都建立了索引

在這裡需要更新表1的物件型別欄位object_type:

--更新資料
UPDATE t_test_1 a
SET    a.object_type =
       (SELECT i.object_type FROM t_test_2 i WHERE i.object_id = a.object_id);

UPDATE t_test_1 a
SET    a.object_type =
       (SELECT i.object_type FROM t_test_2 i WHERE i.object_id2 = a.object_id);

第一條SQL中T_TEST_2的object_id和T_TEST_1中的object_id資料型別是不一致的,而第二條中兩個欄位資料型別是一致的。

我們來看下執行計劃:

SQL> EXPLAIN PLAN FOR
  2  UPDATE t_test_1 a
  3  SET    a.object_type =
  4         (SELECT i.object_type FROM t_test_2 i WHERE i.object_id = a.object_id);
 
Explained
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2933162137
-------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |          | 64296 |  1506K|   137   (3)| 00:00:02 |
|   1 |  UPDATE            | T_TEST_1 |       |       |            |          |
|   2 |   TABLE ACCESS FULL| T_TEST_1 | 64296 |  1506K|   137   (3)| 00:00:02 |
|*  3 |   TABLE ACCESS FULL| T_TEST_2 |   603 | 37989 |   150   (3)| 00:00:02 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(TO_NUMBER("I"."OBJECT_ID")=:B1)
Note
-----
   - dynamic sampling used for this statement
 
19 rows selected

我們可以看到,在這裡Oracle對兩個表都執行了全表掃描。

下面再看另外一句:

[[email protected] ~]$ sqlplus lubinsu/lubinsu

SQL*Plus: Release 10.2.0.1.0 - Production on Sat May 25 12:06:14 2013

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> set timing on
SQL> set autotrace traceonly
SQL> UPDATE t_test_1 a
  2  SET    a.object_type =
  3         (SELECT i.object_type FROM t_test_2 i WHERE i.object_id2 = a.object_id);

49894 rows updated.

Elapsed: 00:00:02.41

Execution Plan
----------------------------------------------------------
Plan hash value: 2786494037

--------------------------------------------------------------------------------
-----------------

| Id  | Operation                    | Name             | Rows  | Bytes | Cost (
%CPU)| Time     |

--------------------------------------------------------------------------------
-----------------

|   0 | UPDATE STATEMENT             |                  | 64296 |  1506K|   137
  (3)| 00:00:02 |

|   1 |  UPDATE                      | T_TEST_1         |       |       |
     |          |

|   2 |   TABLE ACCESS FULL          | T_TEST_1         | 64296 |  1506K|   137
  (3)| 00:00:02 |

|   3 |   TABLE ACCESS BY INDEX ROWID| T_TEST_2         |   603 | 14472 |     6
  (0)| 00:00:01 |

|*  4 |    INDEX RANGE SCAN          | IND_T_TEST_2_ID2 |   241 |       |     1
  (0)| 00:00:01 |

--------------------------------------------------------------------------------
-----------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("I"."OBJECT_ID2"=:B1)

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
        448  recursive calls
     101974  db block gets
     100838  consistent gets
        110  physical reads
   23668060  redo size
        668  bytes sent via SQL*Net to client
        658  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
         11  sorts (memory)
          0  sorts (disk)
      49894  rows processed

--排版不好,整理下:
SQL> set linesize 200
SQL> /

49894 rows updated.

Elapsed: 00:00:03.98

Execution Plan
----------------------------------------------------------
Plan hash value: 2786494037

-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT             |                  | 64296 |  1506K|   137   (3)| 00:00:02 |
|   1 |  UPDATE                      | T_TEST_1         |       |       |            |          |
|   2 |   TABLE ACCESS FULL          | T_TEST_1         | 64296 |  1506K|   137   (3)| 00:00:02 |
|   3 |   TABLE ACCESS BY INDEX ROWID| T_TEST_2         |   603 | 14472 |     6   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN          | IND_T_TEST_2_ID2 |   241 |       |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("I"."OBJECT_ID2"=:B1)

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
        326  recursive calls
     101033  db block gets
     100815  consistent gets
          0  physical reads
   12975952  redo size
        676  bytes sent via SQL*Net to client
        658  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
         11  sorts (memory)
          0  sorts (disk)
      49894  rows processed

SQL> 
可見這裡,是走了索引的。END-lubinsu.

相關推薦

資料型別一致導致SQL索引

前幾天,同事發來一條SQL,說是更新操作的時候執行的很慢,我看了下,資料量也不是很大。再檢視執行計劃,發現是執行路徑錯誤導致的,可是為什麼會走錯誤的執行路徑呢?統計資訊並沒有太大的問題。在這裡模擬下: 資料準備: --1.資料準備,表一: DROP TABLE t_tes

Mysql中欄位型別一致導致索引無效的處理辦法

前兩天有個同事算資料,寫出來的sql執行很慢。那個sql也很簡單,就是一個左聯帶條件的查詢。explain之後發現,其中有一張表沒有用到索引。初始以為是沒有建索引,於是建上索引再試,發現問題依舊。後來查看錶結構才發現,原來用來做關聯的欄位是一個varchar型別的欄位,而聯接

Newtonsoft.Json 版本一致導致錯誤

gre newton code depend binding ken redirect 不一致 -c 可以在配置文件添加這部分,其他版本的不一致,也可使用這種方式解決. <runtime> <assemblyBinding xmlns="ur

jdk 版本一致導致的錯誤

sdn res myeclipse pan 問題 get target 搜索 文件導入 平時做項目時難免會從git,svn下載代碼或者把別人的項目文件導入到自己的MyEclipse中進行操作,因此會遇到很多問題,常見的有一種是使用的jdk版本不一致造成的報錯, 錯誤案例:

華為和H3C交換機NTP version一致導致時間無法同步解決辦法

有效 一個 一分鐘 服務器配置 原因 ESS 服務器 官方文檔 play 昨天給客戶內網網絡設備配置NTP服務,用的華為9303做的NTP服務器,其它設備為NTP客戶端。但是華為所有設備成功同步到NTP服務器,而H3C設備均無法正常同步。華為交換機作為服務器配置如下:ntp

namenode namespaceID與datanode namespaceID 一致導致datanode無法啟動的問題

csdn sdn enter .net oot 改版 more version 進入 在啟動hadoop之後,發現如下datanode何在?????在重新啟動hadoop的時候,發現了問題,如下這說明datanode啟動時出錯了我們跟蹤這個問題,進入到log文件夾下,找到h

Greenplum hostname和address一致導致配置文件無法加載

系統表 clas pst sysconfig href ado 其他 時報 segment 最近又遇到了幾個坑,逐一記錄分析下。 1、主機名hostname和address不一致 在又一次部署壓測環境交由測試組進行壓測時,同事修改了pg_hba.conf文件重新加載配置

Greenplum hostname和address一致導致配置檔案無法載入

最近又遇到了幾個坑,逐一記錄分析下。   1、主機名hostname和address不一致 在又一次部署壓測環境交由測試組進行壓測時,同事修改了pg_hba.conf檔案重新載入配置檔案時報錯。(找不到localhost.localdomain伺服器) 看到這個報錯時,我仔細回想,我是對

SpringBoot測試:pom檔案版本重複和一致導致的問題xxxConfigurationPropertySource和Assert.state(ZLjava/util/function/Supp

測試YAML配置檔案獲取值時遇到的問題:注意:------自己編寫測試類才可能遇到問題,快速生成的工程不會出現 -----------------------------------------------***測試使用的SpringBoot版本為1.5.9*** (1) 使用Idea IDE匯入註

react-native 解決微信分享、微信支付 因簽名一致導致的分享失敗

當我們在做微信微博sdk分享的時候除錯非常麻煩,因為要使用對應的簽名版本才能呼叫sdk成功。 當我們使用AndroidStudio的Gradle之後會很簡單的解決這個問題。 1.我們把簽名檔案放到工程根目錄下(這樣做是為了保持路徑的統一) 2.在Gradle中引入如下程

由於qemu-kvm 版本一致導致openstack遷移失敗

背景: 由於openstack雲平臺壓力過大,擴容了3臺計算節點。基礎環境略。 因以前擴容過計算節點,有現成的指令碼,本以為這次擴容so easy,但過程卻很坎坷,所以記錄以下,以備後患。 流程: 上架、裝機、聯網,非常順利,接下來輪到我裝了,按照指令碼跑了一遍,發現系

最新版SEMCMS_PHP_3.5 過濾導致sql注入

  一、漏洞分析   在分析過程中看到網上已經有人發現semcms V2.4存在過濾不嚴導致sql注入的漏洞,不知道咋還沒改,而且最新版過濾的關鍵字更少了。   首先檢視首頁檔案index.php的程式碼 1 <?php 2 include_once 'Include/web_inc.ph

Unsupported major.minor version 51.0解決辦法 jdbc連結時候報錯,或部署專案後版本一致導致

 這個錯誤時因為JDK版本的問題,比如本機的JDK為1.6,但是專案編譯時用的JDK為1.7那麼就會出現這個異常,因為本機JDK版本較低不能執行編譯版本為高版本的Class檔案,各JDK版本對應的錯誤編號如下: J2SE 8 = 52, J2SE 7 = 51, J2SE 

VMWare 虛擬網路連線設定與主機設定一致導致虛擬機器無法連線網路的解決辦法

最近閒來無事,將家裡的電腦帶到了公司。開啟虛擬機器打算玩玩Linux。 (~ ̄▽ ̄)→))* ̄▽ ̄*)o發現我的Ubuntu竟然連不上網了。 這時候習慣性的google此問題,哎,忘記公司沒有vpn。哭死。好吧那就問問度娘吧,不問不知道,一問嚇一跳啊,這種問題

float元素浮動後高度一致導致錯位的解決辦方法

1、給父元素定義font-size:0; 浮動子元素定義需要的font-size, 再定義display:inline-block;vertical-align:top;  ul{  margin:0;  padding:0;  list-style-type:none; 

tomcat伺服器時間與win系統時間一致,是tomcat設定的時區一致導致

今天在tomcat伺服器上排查一個bug時發現,伺服器上的時間和系統的時間不一致,導致通過日誌定位bug比較吃力,而導致時間不一致是tomcat設定的時區和系統不一致導致的。以下是我的處理:到tomcat目錄下的bin資料夾中,找到catalina.bat檔案,使用筆記本開啟

解決依賴庫版本一致導致的問題

我們在寫程式碼時候總會借鑑一些第三方庫,有的是別人寫的比較優秀的,有的則是google官方提供的,但是我們在依賴之後編譯執行時候總會出各種各樣的問題:1、Error:Execution failed for task ':app:transformDexArchiveWith

Android之Gson時間格式一致導致後臺解析錯誤問題

採用Gson封裝Json資料與後臺進行互動,Android端與後臺介面通常對資料中的Date格式需要做統一處理,這樣就能保證Gson正常解析。但在不同的jdk版本的環境中,這樣處理也不能百分百保證沒有

修改作業系統密碼,導致SQL能啟動的解決辦法

1.我的電腦--控制面板--管理工具--服務--右鍵MSSQLSERVER(代理服務為:SQLSERVERAGENT)--屬性--登陸--登陸身份--選擇"本地系統帳戶"或:2.我的電腦--控制面板--管理工具--服務--右鍵MSSQLSERVER(代理服務為:SQLSERV

openssl 標頭檔案和庫檔案版本一致導致crash

問題描述: Linux下libA依賴於Openssl,程序B> gdb除錯發現,到27行時,md=0x0,ctx中的各項都是空的。而正常情況下除錯的結果都是有意義的值。 解決: 在build libA時,在Makefile中指定openssl 的include路徑,