iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Oracle学习(八) --- SQL优化
  • 270
分享到

Oracle学习(八) --- SQL优化

Oracle学习(八)---SQL优化 2019-07-03 20:07:22 270人浏览 才女
摘要

1、前置工具:执行计划 Explain Plan 1.1、概念 一条查询语句在 oracle 中的执行过程或访问路径的描述。即就是对一个查询任务,做出一份怎样去完成任务的详细方案。 执行计划:用于记录sql执行每一个细节。 执行计划目的:

Oracle学习(八) --- SQL优化

1、前置工具:执行计划 Explain Plan

1.1、概念

一条查询语句在 oracle 中的执行过程或访问路径的描述。即就是对一个查询任务,做出一份怎样去完成任务的详细方案。

  • 执行计划:用于记录sql执行每一个细节。
  • 执行计划目的:通过分析SQL执行每一个细节,从而确定优化方案。

1.2、Oracle执行计划

  • 方式1:使用SQL语句进行查询,结果更加详细。

    --运行“执行计划”: explain plan for SQL语句;
    explain plan for select * from dual;
    --查询“执行计划”结果(固定语句)
    select * from table(dbms_xplan.display());
    
  • 方式2:使用PL/SQL Dev 工具提供"执行计划窗口"进行查询,内容相对而言少一些。

1.3、执行原则

  • 执行计划原则:由上而下、从右向左。
    • 由上至下:在执行计划中一般含有多个节点,相同级别(或并列)的节点,靠上的优先执行,靠下的后执行
    • 从右向左:在某个节点下还存在多个子节点,先从最靠右的子节点开始执行
  • 一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的。
字段 解释
ID 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
Operation 当前操作的内容。
Rows 当前操作的Cardinality,Oracle估计当前操作的返回结果集。
Cost(CPU) Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。
Time Oracle 估计当前操作的时间。

2、准备数据

2.1、前置技术演示

  • 前置技术:
    • 随机数字、随机字符串
    • 重复执行次数
    • 系统时间处理
    • 根据查询结果创建表
-- 2 准备数据

--- 2.1 获得随机数据  dbms_random
-- dbms_random.value(a,b) 生产[a,b) 之间 一个随机数
-- dbms_random.string(符号,数量) 根据"符号"生产指定“长度”随机字符串
---- 符号:u 大写字母、l 小写字母、x 大写字母和数字、a 混合型(大小写) 、p 可打印
-- 1.1) 获得一个 1-10 随机浮点数
select dbms_random.value(1,10) from dual;

-- 1.2) 获得一个 1-10 随机整数
select round( dbms_random.value(1,10) ) from dual;
select trunc( dbms_random.value(1,10) ) from dual;

-- 2) 获得长度为6的随机字符串
select dbms_random.string("u",6) from dual;
select dbms_random.string("l",6) from dual;
select dbms_random.string("x",20) from dual;
select dbms_random.string("a",6) from dual;
select dbms_random.string("p",6) from dual;


-- 2.2 控制查询条件(重复执行次数)
select dbms_random.string("a",6) from dual 
 connect by level <= 10;

-- 2.3 系统时间
-- 1) 当前系统时间
select to_char(sysdate , "yyyy-mm-dd hh24:mi:ss") from dual;
select to_char(sysdate + 1000000/24/3600 , "yyyy-mm-dd hh24:mi:ss") from dual;

-- 2.4 根据查询结果创建表
-- 语法:  create table 表名 as  查询语句;
--- 1) 查询
select trunc( dbms_random.value(18,120) ) age , dbms_random.string("x",4) name from dual;
--- 2) 创建
create table t_person
as
select trunc( dbms_random.value(18,120) ) age , dbms_random.string("x",4) name from dual;


2.2、准备1千万条数据

  • 约耗时3-10分钟
--- 准备1千万条数据
create table t_user
as
select 
  rownum as id,
  to_char(sysdate + rownum / 24 / 3600 , "yyyy-mm-dd hh24:mi:ss") as birthday,
  trunc( dbms_random.value(18,140) ) as age,
  dbms_random.string("x",20) as username
from dual
connect by level <= 10000000;

  • 生成表之后,插入一百万条测试数据
insert into t_user(ID, birthday,age,username)
	select 1000000+rownum as id,
        to_char(sysdate + rownum/24/3600, "yyyy-mm-dd hh24:mi:ss") as birthday,
        trunc(dbms_random.value(0, 100)) as age,
        dbms_random.string("x", 20) username
    from dual
  		connect by level <= 1000000;

3、优化

3.1、使用索引(可以大大提高检索速度)

--优化1:使用索引
-- 未使用搜索 2.480
select * from t_user where id = 1;
-- 设置主键,自带唯一索引
alter table t_user add constraint user_pk primary key (id);
-- 创建索引后 0.046
select * from t_user where id = 1;

3.2、避免在WHERE字句中使用NULL

  • 使用null,讲放弃索引,进行全表扫描
--优化2:避免在where中使用null
-- 1) 给age添加普通索引
create index user_age_index on t_user(age);
-- 2) 查询age = 18所有信息  0.051
select * from t_user where age = 18;
-- 3) 更新id=1 age为null
update t_user set age = null where id = 1;
commit;
-- 4) 查询null数据
-- 查看age是否为null,0.058
select * from t_user where id = 1;
-- 根据null查询,1.396
select * from t_user where age is null;

3.3、尽量不使用不等于(<>或 !=)

  • 使用不等于,将进行全表扫描

3.4、应尽量避免在 where子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描

  • 避免部分条件放弃索引,进行全表扫描
-- 优化4 :
--- 查询所有
select * from t_user;
-- 0.031
select * from t_user where id = 15;
-- 1.282
select * from t_user where username = "NNH250Y9LN7JHA13G1T3";
-- or 操作 1.846
select * from t_user where id = 15 or username = "NNH250Y9LN7JHA13G1T3";

--- 优化方案:使用 uNIOn all 替换 or  -- 1.361
select * from t_user where id = 15
union all
select * from t_user where username = "NNH250Y9LN7JHA13G1T3";

3.5、避免使用 select *

-- 优化5:避免使用 select *
--- id 查询
select * from t_user where id = 6000000;
--- 通过username查询 -- 1.416
select * from t_user where username = "C2Q0Q9INJDTDZ9TLN8JG";
--- 字段替换*  -- 1.309
select id,username,age,birthday from t_user where username = "C2Q0Q9INJDTDZ9TLN8JG";

3.6、尽量不用 like 语句,如果必须使用,优先使用"xx%"

-- 优化6:尽量不用like语句,如果必须使用,优先使用"xx%"
----  "%xx" 和 "%xx%" 不能使用索引
-- 1) 给 t_user username 添加索引
create index user_username_index on t_user(username);
-- 2) 使用 %xx% 进行模糊查询 -- 3.825
select * from t_user where username like "%C2Q0Q9IN%";
-- 3) 使用 xx% 进行模糊查询 -- 0.053
select * from t_user where username like "C2Q0Q9IN%";

3.7、避免在 where 子句中对字段进行表达式

-- 优化7:避免在 where 子句中对字段进行表达式
-- 所有 60 岁人员
select * from t_user where age = 60;
-- 对 age 进行计算
select * from t_user where age / 2 = 30;

3.8、避免在 where 子句使用函数

-- 优化8:避免where子句使用函数
--- 使用substr(开始位置,长度)
select substr(username,2,3) from t_user where id = 6000000;
select length("C2Q0Q9IN") from dual;
--- 判断前缀 -- 2.959
select * from t_user where substr(username, 1, 8) = "C2Q0Q9IN";
select * from t_user where substr(username, 1, length("C2Q0Q9IN")) = "C2Q0Q9IN";
-- 使用like 替换函数
select * from t_user where username like "C2Q0Q9IN%";

3.9、复合索引中,必须使用索引中第一个字段,且尽量字段顺序与索引顺序一致

-- 优化10:复合索引中,必须使用索引中第一个字段,且尽量字段顺序与索引顺序一致
-- 1)创建表(复合主键)
create table t_user2(
  firstname varchar2(20),
  secondname varchar2(20),
  age int,
  constraint user2_fk primary key (firstname,secondname)
);
-- 2)初始化 100w条数据
-- 语法: insert into 表名 select语句;
-- 2.1) 查询结果
select dbms_random.string("x",20) as firstname,
    dbms_random.string("x",20) as secondname,
    trunc(dbms_random.value(0,100) ) as age
from dual
connect by level <= 10;

-- 2.2) insert 100w
insert into t_user2(firstname,secondname,age)
select dbms_random.string("x",20) as firstname,
    dbms_random.string("x",20) as secondname,
    trunc(dbms_random.value(0,100) ) as age
from dual
connect by level <= 1000000;
-- 提交事务
commit;

-- 3)测试:查询第一字段、查询第二字段、查询第一 + 二字段
--- 3.1) 查询id 700000
select * from (
  select rownum r ,t_user2.* from t_user2
) t where t.r = 700000;
--- 3.2) 查询firstname -- 0.023 (速度快一些)
select * from t_user2 where firstname = "PR9AVGGXEJL4SJ8OCZWF";
--- 3.3) 查询secondname  -- 0.068 (相对而言慢一些)
select * from t_user2 where secondname = "93A0SPRCXQBZ45V1S59A";
--- 3.4) 查询firstname + secondname (字段顺序无关,建议顺序一致)
select * from t_user2 where firstname = "PR9AVGGXEJL4SJ8OCZWF" and secondname = "93A0SPRCXQBZ45V1S59A";
select * from t_user2 where secondname = "93A0SPRCXQBZ45V1S59A" and firstname = "PR9AVGGXEJL4SJ8OCZWF";

3.10、构建空表

-- 优化11:创建空表结构
-- 1) select into 不能生成空表结构
-- select 字段1,字段2,... into 新表名 from 查询表 where 1=0;
-- 1.1) select into 在Oracle无法创建表结构
-- select id,birthday,age,username into t_user3 from t_user where id < 10;

-- 2) 创建表结构,但没有数据
create table t_user3
as
select 
  dbms_random.string("x",20) as firstname, dbms_random.string("x",20) as secondname
from dual where 1 = 0;

3.11、根据实际情况创建索引,而不是越多越好。

  • 添加索引提供查询速度,同时降低了insert 和 update效率。

3.12、使用 exists 和 in 对比

  • 两个表中数据一致的情况下,没有差异
  • 如果两个表中一个数据较小A,一个是数据较多B,则子查询B用exists,子查询A用in
--如果部门名称中含有字母A,则查询所有员工信息(使用exists)

-- 1) 查询 部门名称中含有字母A
select * from dept where dname like "%A%";

-- 2) 使用exists
select * from emp where exists ( select * from dept where dname like "%A%" and dept.deptno = emp.deptno )

-- 3) in
select * from emp where emp.deptno in ( select dept.deptno from dept where dname like "%A%" )

您可能感兴趣的文档:

--结束END--

本文标题: Oracle学习(八) --- SQL优化

本文链接: https://www.lsjlt.com/news/6527.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python学习——【第八弹】
    前言 上篇文章 python学习——【第七弹】学习了python中的可变序列集合,自此python中的序列的学习就完成啦,这篇文章开始学习python中的函数。 函数 在学习其他编程语言的时候我们就...
    99+
    2023-09-26
    python 学习 开发语言 压栈 函数
  • Python3学习(八):使用sched
    python中有一个轻量级的定时任务调度的库:schedule。他可以完成每分钟,每小时,每天,周几,特定日期的定时任务。因此十分方便我们执行一些轻量级的定时任务。 代码如下: import schedule import time ...
    99+
    2023-01-31
    sched
  • python 学习 第八篇 jquery
    简介:jQuery是一个javascript库。极大滴简化了javascript编程。包含内容:HTML 元素选取HTML 元素操作CSS 操作HTML 事件函数JavaScript 特效和动画HTML DOM 遍历和修改AJAX1:下载 ...
    99+
    2023-01-31
    第八篇 python jquery
  • 如何用机器学习优化SQL拼接查询
    使用机器学习优化SQL拼接查询可以通过以下步骤实现: 数据准备:收集和准备用于训练的数据集,包括已有的SQL查询语句和其对应的性...
    99+
    2024-04-29
    SQL 机器学习
  • 学习笔记-小甲鱼Python3学习第八讲
    按照100分制,90分以上成绩为A,80到90为B,60到80为C,60以下为D,写一个程序,当用户输入分数,自动转换为ABCD的形式打印。使用if 条件:...elif 条件:...else...循环fenshu0 = input('请输...
    99+
    2023-01-31
    甲鱼 学习笔记 第八讲
  • 学习笔记-小甲鱼Python3学习第十八
    形参和实参>>>def MyFirstFunction(name):            '函数定义过程中的name是形参'            #因为它只是一个形式,表示占据一个参数位置            pri...
    99+
    2023-01-31
    甲鱼 学习笔记
  • mysql学习13:第八章:锁
      1.   锁 InnoDB支持行锁,有时升级为表锁。 MyISAM只支持表锁。 表锁:开小小,加锁快,不会出现死锁;锁粒度大,锁冲突概率高,并发度低。 ...
    99+
    2024-04-02
  • day 88 Vue学习之八geetes
      本节目录 一 geetest前端web中使用 二 xxx 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 geetest前端web中使用     下载gt文件,官网...
    99+
    2023-01-31
    day geetes Vue
  • Python学习之旅(三十八)
    二、MySQL MySQL是Web世界中使用最广泛的数据库服务器。SQLite的特点是轻量级、可嵌入,但不能承受高并发访问,适合桌面和移动应用。而MySQL是为服务器端设计的数据库,能承受高并发访问,同时占用的内存也远远大于SQLite...
    99+
    2023-01-30
    之旅 Python 三十八
  • Oracle性能优化-SQL优化(案例四)
    Oracle 性能优化 -SQL 优化 ( 案例四 ) 环境: DB:Oracle 11.2.0.1.0 问题: ERP 薪资发放节点计算时间耗时 较长,需要15 分钟左右; ...
    99+
    2024-04-02
  • oracle SQL优化器SQL Tuning Advisor (STA)
    一  创建测试数据 SQL> conn scott/oracle Connected. SQL> create table obj as select * from...
    99+
    2024-04-02
  • Python学习笔记整理(八)Pytho
      程序由模块构成 模块包含语句 语句包含表达式 表达式建立并处理对象 一、Python语句 语句 角色 列子 赋值 创建引用 a,b,c='good','bad...
    99+
    2023-01-31
    学习笔记 Python Pytho
  • Python第八周 学习笔记(1)
    基本概念个体继承自父母,继承了父母的一部分特征,但也可以有自己的个性 子类继承了父类,就直接拥有了父类的属性和方法,也可以定义自己的属性、方法,甚至对父类的属性、方法进行重写 Python继承实现 class Cat(Anima...
    99+
    2023-01-31
    学习笔记 Python
  • Django学习之八:forms组件【对
    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段...
    99+
    2023-01-30
    组件 Django forms
  • 我的python学习--第七、八天
    Flask的HTTP方法HTTP(与web应用会话的协议)有许多不同的URL方法。默认情况下,路由只回应GET请求,但是通过route()装饰器传递methods参数可以改变这个行为。HTTP方法告知服务器,客户端想对请求的页面 做些什么。...
    99+
    2023-01-31
    python
  • Oracle 学习之性能优化(七)join的实现方式
      本文讨论一下join技术背后的机制。我们知道常用的表连接有如下几种笛卡尔连接内连接左外连接右外连接全连接这些sql的写法,想必大家都很清楚了,那么这些连接的数据访问是如何实现的呢?nested...
    99+
    2024-04-02
  • Oracle系列:(31)Oracle SQL语句优化
    (01)选择最有效率的表名顺序(笔试常考)       ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,     &nb...
    99+
    2024-04-02
  • 八、IO优化(3)稀疏列
    一、Nullable  在设计表时,有时会允许某列可以使用Null值(默认)。CREATE TABLE [dbo].[EmpTable2]([EmpID] [varchar](10) NOT NULL,[DepID] [nvarc...
    99+
    2023-01-31
    稀疏 IO
  • oracle SQL优化规则有哪些
    这篇文章主要讲解了“oracle SQL优化规则有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“oracle SQL优化规则有哪些”吧! 1>选...
    99+
    2024-04-02
  • 黑马B站八股文学习笔记
    视频地址:https://www.yuque.com/linxun-bpyj0/linxun/vy91es9lyg7kbfnr 大纲 基础篇 基础篇要点:算法、数据结构、基础设计模式 1. 二分查找...
    99+
    2023-09-05
    学习 笔记 java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作