使用or展开进行sql优化(即sql语法union all代替or可以提高效率)
问题:
这样一条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可以提高效率)的更多相关文章
- [terry笔记]Oracle SQL 优化之sql tuning advisor (STA)
前言:经常可以碰到优化sql的需求,开发人员直接扔过来一个SQL让DBA优化,然后怎么办? 当然,经验丰富的DBA可以从各种方向下手,有时通过建立正确索引即可获得很好的优化效果,但是那些复杂SQL错综 ...
- SQL优化之SQL 进阶技巧(下)
上文( SQL优化之SQL 进阶技巧(上) )我们简述了 SQL 的一些进阶技巧,一些朋友觉得不过瘾,我们继续来下篇,再送你 10 个技巧 一. 使用延迟查询优化 limit [offset], [r ...
- SQL优化之SQL 进阶技巧(上)
由于工作需要,最近做了很多 BI 取数的工作,需要用到一些比较高级的 SQL 技巧,总结了一下工作中用到的一些比较骚的进阶技巧,特此记录一下,以方便自己查阅,主要目录如下: SQL 的书写规范 SQL ...
- oracle11g中SQL优化(SQL TUNING)新特性之SQL Plan Management(SPM)
1. 简介 Oracle Database11gR1引进了SQL PlanManagement(简称SPM),一套允许DBA捕获和保持任意SQL语句执行计划最优的新工具,这样,限制了刷新优化器统计 ...
- Oracle12c中SQL优化(SQL TUNING)新特性之SQL计划指令
SQL计划指令是Oracle12c中自适应查询优化的功能之一.SQL计划指令就像“额外的提醒” ,用以提醒优化器你先前选择了的计划并不是最优的,典型的是因为错误的势评估.错误的势评估往往是由统计信息缺 ...
- SQL优化(SQL TUNING)可大幅提升性能的实战技巧之一——让计划沿着索引跑
我们进行SQL优化时,经常会碰到对大量数据集进行排序,然后从排序后的集合取前部分结果的需求,这种情况下,当我们按照常规思路去写SQL时,系统会先读取过滤获得所有集合,然后进行排序,再从排序结果取出极少 ...
- SQL优化- 数据库SQL优化——使用EXIST代替IN
数据库SQL优化——使用EXIST代替IN 1,查询进行优化,应尽量避免全表扫描 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 . 尝试下面的 ...
- 【SQL优化】SQL优化工具
SQLAdvisor 是由美团点评公司北京DBA团队开发维护的 SQL 优化工具:输入SQL,输出索引优化建议. 它基于 MySQL 原生词法解析,再结合 SQL 中的 where 条件以及字段选择度 ...
- Oracle自带工具sql优化集-SQL Tuning Advisor (使用心得体会)
如何有效的诊断和监控高负载的SQL对于DBA来说并非是件容易的事情,对SQL语句手工调优需要很多的经验和技巧, 结合个人经验常见如下问题: . 对SQL语句本身进行优化以便获得更优的 ...
随机推荐
- php纯原生实现数组二分法
代码如下 $arr = [1,3,5,7,9];//$arr = range(1,10000);var_dump(find($arr, 2)); function find(array $arr, $ ...
- yii2的Console定时任务创建
Yii2的定时任务可以有两种写法,原理都是通过服务器的定时任务去调用 1.通过调用指定的URL访问 就相当于在浏览器中访问 2.通过console调用 下面我们就来说说Console 是如何实现定时任 ...
- IPV6设置
C:\Windows\System32\drivers\etc 目录下修改hosts文件. 网上有更新的ipv6 hosts文件,复制下来~ 别人不断更新的: https://raw.githubus ...
- Windows路径操作API函数学习
前言 在VC++开发过程中,经常需要用到一些路径操作,比如拼需要的文件路径,搜索路径中的内容等等.Windows提供了一套关于路径操作的API帮助我们更好的执行这些操作. 路径截断与合并API Pat ...
- C#操作MSMQ(消息队列)
using System; using System.Collections.Generic; using System.Text; using System.Messaging; using Sys ...
- consul读取key value
1.nuget 搜索consul安装 2. using (var client = new ConsulClient()) { var kvPair = client.KV.Get(key).Resu ...
- SSHLibrary库关键字汇总
红色框的部分是设置系统用户标识符(不可缺少):$表示非超级用户 #表示超级用户
- Python3 urllib 库
urllib 简介 urllib 基础模块 使用 urllib 发送请求 使用 urllib 构造请求对象 关于 Handler 与 opener 使用 urllib 进行身份验证 使用 urllib ...
- memcache和memcached的区别
用了段时间的memcache和memcached总结下认识,看很多人在用cache的时候,刚刚都没有搞清楚memcache和 memcached的区别,还有就是使用的时候基本都是 get/set 用 ...
- linux发布项目
1.右击项目 export --->war file 上传到linux服务器 2.解压 jiar -xvf xx.war 3.移动到 tomcat webapps文件中 4.启动tomcat 访 ...