Home  >  Article  >  Database  >  数据类型不一致导致的SQL不走索引

数据类型不一致导致的SQL不走索引

WBOY
WBOYOriginal
2016-06-07 17:29:291220browse

前几天,同事发来一条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

linux

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn