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

來源:互聯網
上載者:User

前幾天,同事發來一條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

  • 1
  • 2
  • 3
  • 下一頁

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.