问题:

这样一条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. Ubuntu系统启动报错:The system is running in low-graphics mode

    最近,不小心将自己的Ubuntu-12.04桌面系统搞坏了,主要是由于改变了/var目录下文件的属主,结果桌面系统崩溃了,启动都成问题了.不过还算幸运,可以通过其他的机器登录到我的系统上.根据别人的系 ...

  2. jquery -- checkbox选中无选中状态

    最近在工作中使用jquery操作checkbox,使用下面方法进行全选.反选: var ischecked=allCheckObj.is(':checked'); ischecked?checksOb ...

  3. perl 中的哈希赋值

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

  4. Linux的缓存内存 Cache Memory详解

    http://www.ha97.com/4337.html PS:前天有童鞋问我,为啥我的Linux系统没运行多少程序,显示的可用内存这么少?其实Linux与Win的内存管理不同,会尽量缓存内存以提高 ...

  5. MathType初级教程:怎么安装MathType

    MathType 由美国Design Science公司开发,是一款功能强大的数学公式编辑器,它同时支持Windows和Macintosh 两种操作系统,有很好的兼容性,能够在各种文档中加入复杂的数学 ...

  6. [转] COM编程总结

    一.Com概念 所谓COM(Componet Object Model,组件对象模型),是一种说明如何建立可动态互变组件的规范,此规范提供了为保证能够互操作,客户和组件应遵循的一些二进制和网络标准.通 ...

  7. oracle 中 cursor 与refcursor及sys_refcursor的区别 (转载)

    http://blog.csdn.net/gyflyx/article/details/6889028 引用一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明确的声明的cursor ...

  8. Strut2------获取界面返回的session,application,parameter

    1.Action类下的代码 public class ServletActionDemo extends ActionSupport { @Override public String execute ...

  9. PHP-006

    Q:应用程序执行时的路径 "D:\*******\protected\runtime" 是无效的. 请确定它是一个可被 Web server process 写入资料的目录. A: ...

  10. MySQL只有information_schema,test两个数据库

    一.现象 1.今天登上数据库,用 mysql -uroot -proot 登录(本人密码是root),出现: 2.然后尝试 无密码登录,竟然登录成功: 3.查看mysql中的数据库,发现只有两个系统表 ...