问题:

这样一条sql应该怎么优化?

select * from sys_user

where user_code = 'zhangyong'

or user_code in

(select grp_code

from sys_grp

where sys_grp.user_code = 'zhangyong')

Execution Plan

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

0  SELECT STATEMENT Optimizer=RULE

1  0   FILTER

2  1     TABLE ACCESS (FULL) OF 'SYS_USER'

3  1     INDEX (UNIQUE SCAN) OF 'PK_SYS_GRP' (UNIQUE)

Statistics

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

14  recursive calls

4  db block gets

30590 consistent gets

0  physical reads

0  redo size

1723  bytes sent via SQL*Net to client

425  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

3  rows processed

里面的查询返回的记录数一般只有一两条,但sys_user表的数据很多,怎么样才能让这条sql以sys_grp为驱动表?

表中记录情况如下:

SQL> select count(*) from sys_grp;

COUNT(*)

----------

25130

SQL> select count(*) from sys_user;

COUNT(*)

----------

15190

优化:

降低逻辑读是优化SQL的基本原则之一

我们尝试通过降低逻辑读来加快SQL的执行.

这里我们使用or展开来改写SQL查询:

select * from sys_user where user_code = 'zhangyong'

union all

select * from sys_user where user_code <> 'zhangyong'

and user_code in (select grp_code from sys_grp where sys_grp.user_code = 'zhangyong')

Statistics

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

0  recursive calls

0  db block gets

130 consistent gets

0  physical reads

0  redo size

1723  bytes sent via SQL*Net to client

425  bytes received via SQL*Net from client

2  SQL*Net roundtrips to/from client

1  sorts (memory)

0  sorts (disk)

3  rows processed

Execution Plan

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

0      SELECT STATEMENT Optimizer=RULE

1    0   UNION-ALL

2    1     TABLE ACCESS (BY INDEX ROWID) OF 'SYS_USER'

3    2       INDEX (UNIQUE SCAN) OF 'PK_SYS_USER' (UNIQUE)

4    1     NESTED LOOPS

5    4       VIEW OF 'VW_NSO_1'

6    5         SORT (UNIQUE)

7    6           TABLE ACCESS (BY INDEX ROWID) OF 'SYS_GRP'

8    7             INDEX (RANGE SCAN) OF 'FK_SYS_USER_CODE' (NON-UNIQUE)

9    4       TABLE ACCESS (BY INDEX ROWID) OF 'SYS_USER'

10    9         INDEX (UNIQUE SCAN) OF 'PK_SYS_USER' (UNIQUE)

我们注意到,通过改写,逻辑读减少到130,从30590到130这是一个巨大的提高,减少逻辑读最终会减少资源消耗,提高SQL的执行效率.这个改写把Filter改为了Nest LOOP,索引得以充分利用.从而大大提高了性能.

我们同时注意到,这里引入了一个排序

排序来自于这一步:

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

6  5  SORT (UNIQUE)

7  6    TABLE ACCESS (BY INDEX ROWID) OF 'SYS_GRP'

8  7       INDEX (RANGE SCAN) OF 'FK_SYS_USER_CODE' (NON-UNIQUE)

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

在'SYS_GRP'表中,user_code 是非唯一键值

在in值判断里,要做sort unique排序,去除重复值

这里的union all是不需要排序的

使用or展开进行sql优化(即sql语法union all代替or可以提高效率)的更多相关文章

  1. [terry笔记]Oracle SQL 优化之sql tuning advisor (STA)

    前言:经常可以碰到优化sql的需求,开发人员直接扔过来一个SQL让DBA优化,然后怎么办? 当然,经验丰富的DBA可以从各种方向下手,有时通过建立正确索引即可获得很好的优化效果,但是那些复杂SQL错综 ...

  2. SQL优化之SQL 进阶技巧(下)

    上文( SQL优化之SQL 进阶技巧(上) )我们简述了 SQL 的一些进阶技巧,一些朋友觉得不过瘾,我们继续来下篇,再送你 10 个技巧 一. 使用延迟查询优化 limit [offset], [r ...

  3. SQL优化之SQL 进阶技巧(上)

    由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...

  4. oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)

    1.   简介 Oracle Database11gR1引进了SQL PlanManagement(简称SPM),一套允许DBA捕获和保持任意SQL语句执行计划最优的新工具,这样,限制了刷新优化器统计 ...

  5. Oracle12c中SQL优化(SQL TUNING)新特性之SQL计划指令

    SQL计划指令是Oracle12c中自适应查询优化的功能之一.SQL计划指令就像“额外的提醒” ,用以提醒优化器你先前选择了的计划并不是最优的,典型的是因为错误的势评估.错误的势评估往往是由统计信息缺 ...

  6. SQL优化(SQL TUNING)可大幅提升性能的实战技巧之一——让计划沿着索引跑

    我们进行SQL优化时,经常会碰到对大量数据集进行排序,然后从排序后的集合取前部分结果的需求,这种情况下,当我们按照常规思路去写SQL时,系统会先读取过滤获得所有集合,然后进行排序,再从排序结果取出极少 ...

  7. SQL优化- 数据库SQL优化——使用EXIST代替IN

    数据库SQL优化——使用EXIST代替IN 1,查询进行优化,应尽量避免全表扫描 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 . 尝试下面的 ...

  8. 【SQL优化】SQL优化工具

    SQLAdvisor 是由美团点评公司北京DBA团队开发维护的 SQL 优化工具:输入SQL,输出索引优化建议. 它基于 MySQL 原生词法解析,再结合 SQL 中的 where 条件以及字段选择度 ...

  9. Oracle自带工具sql优化集-SQL Tuning Advisor (使用心得体会)

    如何有效的诊断和监控高负载的SQL对于DBA来说并非是件容易的事情,对SQL语句手工调优需要很多的经验和技巧, 结合个人经验常见如下问题:          . 对SQL语句本身进行优化以便获得更优的 ...

随机推荐

  1. C/C++,从未过时的编程语言之父

    C/C++,持续火爆的编程语言之父 --訪传智播客C/C++学院院长传智·萧峰 编程语言作为实现互联网+基础必备工具,构建着互联网行业美轮美奂的大时代.作为编程语言之父--C语言,更是如鱼得水,在甘愿 ...

  2. perl 中的哈希赋值

    在perl 中,通过代码动态的给哈希赋值,是最常见的应用场景,但是有些情况下,我们事先知道一些信息,当需要把这些信息存放进一个哈希的时候,直接给哈希赋值就好: 哈希的key不用说,就是一个字符串,关键 ...

  3. 使用Base SDK 6.1编译的APP在iOS7的设备上运行,NavigationBar覆盖view的解决办法

    if (__IPHONE_OS_VERSION_MAX_ALLOWED <= __IPHONE_6_1) { self.navigationController.navigationBar.tr ...

  4. Java Error: java.lang.UnsupportedClassVersionError: ...bad major version at offset=6

    问题分析 报这个错误是指你的jar包或者class 的被编译的jdk版本比当前runtime的jdk版本高. 首先,确定你当前的运行版本: Java代码   Java -version java ve ...

  5. 无法查找或打开 PDB 文件

    emmmmmmmmmmmmm...建议:不用管!!! 参考: 在 Visual Studio 调试器中指定符号 (.pdb) 和源文件 https://msdn.microsoft.com/zh-cn ...

  6. ubuntu下使用sublime text进行C编程开发尝鲜

    1 选择编译系统 2 编写文件,编译(Ctrl+B)运行(Shift+Ctrl+B)

  7. [redis] redis 对string类型数据操作

    package com.xwolf.java.redis; import org.junit.Before; import org.junit.Test; import redis.clients.j ...

  8. A complete example using RAISE_APPLICATION_ERROR : raise_application_error

    from:http://www.java2s.com/Tutorial/Oracle/0480__PL-SQL-Programming/AcompleteexampleusingRAISEAPPLIC ...

  9. QQ第三方登录实例demo(QQSDK包优化)

    实现效果: 实现流程: 1.注冊QQ互联开发人员 QQ互联官网 注冊成为开发人员(须要审核) 2.审核通过之后 申请应用(须要互联人员审核*须要备案成功的线上域名) 以下我们開始下载QQsdk包 QQ ...

  10. PHP-003

    PHP函数大全(转) usleep() 函数延迟代码执行若干微秒.unpack() 函数从二进制字符串对数据进行解包.uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID.time_sl ...