当前位置:首页 > 芯闻号 > 充电吧
[导读]之前对use_nl的理解一直很模糊,看下面的案例。SQL> select *  2    from table_detail t,  3    table(cast(str2varlist('1

之前对use_nl的理解一直很模糊,看下面的案例。

SQL> select *
  2    from table_detail t,
  3    table(cast(str2varlist('123') as vartabletype)) t2
  4   where t.id = t2.column_value;

Execution Plan
----------------------------------------------------------
Plan hash value: 31598426
----------------------------------------------------------
 Operation   | Name   |Rows |Bytes|Cost(%CPU)|Time|
----------------------------------------------------------
SELECT STATEMENT   |      |784K|124M|2132(1)|00:00:26|
 NESTED LOOPS      |      |784K|124M|2132(1)|00:00:26|
  TABLE ACCESS FULL | table_detail|96 |15744| 11(0)|00:00:01|
  COLLECTION ITERATOR PICKLER FETCH| STR2VARLIST |   |  |  | |
-------------------------------------------------------------

t2是个虚拟的表,没有准确的统计信息,很容易出现执行计划错误,这种sql最好要用hint来固化其执行计划。

1.使用/*+ ORDERED use_nl(t2,t) */提示

SQL> select /*+ ORDERED use_nl(t2,t) */*
  2    from table_detail t,
  3    table(cast(str2varlist('123') as vartabletype)) t2
  4   where t.id = t2.column_value;

Execution Plan
----------------------------------------------------------
Plan hash value: 3775534098

----------------------------------------------------------------------------
 Operation                         | Name      |Rows |Bytes|Cost(%CPU)|Time|
----------------------------------------------------------------------------
SELECT STATEMENT                   |            |784K|124M|2132(1)|00:00:26|
 NESTED LOOPS                      |            |784K|124M|2132(1)|00:00:26|
  TABLE ACCESS FULL                | table_detail|96 |15744| 11(0)|00:00:01|
  COLLECTION ITERATOR PICKLER FETCH| STR2VARLIST |   |     |      |        |
----------------------------------------------------------------------------

执行计划是错误的,还是取table_detail为驱动表。
错误理解:使用order提示,执行计划会去取use_nl(t2,t)中的t2作为驱动表。
2.使用/*+ ORDERED use_nl(t,t2) */提示

SQL> select /*+ ORDERED use_nl(t,t2) */*
  2    from table_detail t,
  3    table(cast(str2varlist('123') as vartabletype)) t2
  4   where t.id = t2.column_value;

Execution Plan
----------------------------------------------------------
Plan hash value: 3775534098

----------------------------------------------------------------------------
 Operation                         | Name      |Rows |Bytes|Cost(%CPU)|Time|
----------------------------------------------------------------------------
SELECT STATEMENT                   |            |784K|124M|2132(1)|00:00:26|
 NESTED LOOPS                      |            |784K|124M|2132(1)|00:00:26|
  TABLE ACCESS FULL                | table_detail|96 |15744| 11(0)|00:00:01|
  COLLECTION ITERATOR PICKLER FETCH| STR2VARLIST |   |     |      |        |
----------------------------------------------------------------------------

执行计划还是错误的,这到底是怎么回事?
3.使用/*+ ORDERED use_nl(t,t2) */提示,同时调整了表顺序。

SQL>  select /*+ ORDERED use_nl(t2,t) */*
  2    from table(cast(str2varlist('123') as vartabletype)) t2,
  3         table_detail t
  4   where t.id = t2.column_value;

Execution Plan
----------------------------------------------------------
Plan hash value: 2272521841

-------------------------------------------------------------------------------
 Operation                          | Name       Rows |Bytes |Cost (%CPU)|Time|
-------------------------------------------------- ----------------------------
SELECT STATEMENT                    |              |784K| 124M|25 (0)|00:00:01|
 TABLE ACCESS BY INDEX ROWID        | table_detail | 96 |15744| 1 (0)|00:00:01|
  NESTED LOOPS                      |              |784K| 124M|25 (0)|00:00:01|
   COLLECTION ITERATOR PICKLER FETCH| STR2VARLIST  |    |     |      |        |
   INDEX RANGE SCAN                 | IND_deail_id |  1 |     | 1 (0)|00:00:01|
-------------------------------------------------- ----------------------------

这回执行计划是正确的,原来order是根据from表顺序来决定驱动表,而不是use_nl(t,t2)中表的先后顺序。
调整from后面的表顺序是很老土的调优,仿佛回到了rbo的年代,采用leading指定驱动表看是否可行。
4.使用leading提示来指定驱动表

SQL> select /*+ leading(t2) use_nl(t) */*
  2    from table_detail t,
  3    table(cast(str2varlist('123') as vartabletype)) t2
  4   where t.id = t2.column_value;

Execution Plan
----------------------------------------------------------
Plan hash value: 2272521841
-------------------------------------------------------------------------------
 Operation                          | Name       Rows |Bytes |Cost (%CPU)|Time|
-------------------------------------------------- ----------------------------
SELECT STATEMENT                    |              |784K| 124M|25 (0)|00:00:01|
 TABLE ACCESS BY INDEX ROWID        | table_detail | 96 |15744| 1 (0)|00:00:01|
  NESTED LOOPS                      |              |784K| 124M|25 (0)|00:00:01|
   COLLECTION ITERATOR PICKLER FETCH| STR2VARLIST  |    |     |      |        |
   INDEX RANGE SCAN                 | IND_deail_id |  1 |     | 1 (0)|00:00:01|
-------------------------------------------------- ----------------------------

1./*+use_nl(t2,t) */ 提示走nest loop,但没有提示t2还是t为驱动表 。
2./*+ ordered use_nl(t2,t) */提示走nest loop,order提示的是from后面的第一个表为驱动表。
3./*+ leading(t2) use_nl(t) */ 直接提示t2为驱动表。
结论:use_nl不能让优化器确定谁是驱动表谁是被驱动的表,use_nl(t,t2)也没有指出哪个是驱动表,这时候我们需要使用ordered,leading来强制指定驱动表,以达到我们的目的。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

前言sql优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到。如果某天你负责的某个线上接口,出现了性能问题,需要做优化。那么你首先想到的很有可能是优化sql语句,因为它的改造成本相对于代码来说...

关键字: sql

01—mutable关键字详解与实战在C中mutable关键字是为了突破const关键字的限制,被mutable关键字修饰的成员变量永远处于可变的状态,即使是在被const修饰的成员函数中。在C中被const修饰的成员函...

关键字: table

01—mutable关键字详解与实战在C中mutable关键字是为了突破const关键字的限制,被mutable关键字修饰的成员变量永远处于可变的状态,即使是在被const修饰的成员函数中。在C中被const修饰的成员函...

关键字: table

无论是开发、测试,还是DBA,都难免会涉及到数据库的操作,比如:创建某张表,添加某个字段、添加数据、更新数据、删除数据、查询数据等等。

关键字: 数据库 sql

前言 上一篇总结了Mysql的锁机制,通过读者的反映和阅读量显示,总体还是不错的,感兴趣的可以阅读一下[大厂面试官必问的Mysql锁机制]。 写了那么多的Mysql文章,有读者问我是不是dba,工作真的需要掌握那么深吗。...

关键字: sql

前言 前几天有粉丝和我聊到他找工作面试大厂时被问的问题,因为现在疫情期间,找工作也特别难找。他说面试的题目也比较难,都偏向于一两年的工作经验的面试题。 他说在一面的时候被问到Mysql的面试题,索引那块自己都回答比较满意...

关键字: sql

                        我所写的项目是使用Maven开发,在pom.xml中添加如下必要依赖:         添加com.microsoft.sqlserver的mssql-

关键字: server sql 存储过程

一.Table的逻辑结构 Table也叫SSTable(Sorted String Table),是数据在.sst文件中的存储形式。Table的逻辑结构如下所示,包括存储数据的Block,存储索引信息

关键字: leveldb table

DECLARE @dt datetimeSET @dt=GETDATE()DECLARE @number intSET @number=3--1.指定日期该年的第一天或最后一天--A. 年的第一天SE

关键字: qq sql

/**************************************************************   SQL Server 2012 新增的函数   **********

关键字: server sql
关闭
关闭