- 浏览: 326862 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
zhangliguoaccp:
对于女人不要太看重吧,喜欢你的自然留下,你若盛开,蝴蝶自来!
遇见她 -
yiqi1943:
springtest支持的spring版本最低是多少啊
Spring Test -
WITLP:
爱,我只知道你一部分的事情,没想到你从华智出来这么坎坷
2009 为什么待到毕业时? -
WITLP:
哈哈,原来你就是传说中的欧阳平?
ANT 简单使用 -
bo_hai:
谢谢。总结的很好。
工具 PL/SQL 快捷键
转自: http://www.iteye.com/articles/2516
正如Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能的例子一样,对于所测试的app_user表,3百万条记录,对于select * from scott.app_user where abs(user_id) = 100000;这条sql,直接在user_id上建索引对这条SQL的访问是没有时间上的改进的,因为在这样的情况下,本质上B树上存的是user_id的值,而不是abs(user_id)的值,所以Oracle采取了全表扫描的方式来访问数据库。
解决这样问题的方法就是在app_user表上建一个abs(user_id)的函数索引,相当于多了一个虚拟列abs(user_id),然后在这个虚拟列上建索引;可以看到执行计划相差较大,从统计信息分析,IO操作少了很多。
1. 概要
昨天在Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能说明了索引对select语句的巨大性能提高,今天,来看一种情况,就是在where语句中,在索引列上有函数操作时,普通的索引并不会发生作用,需要使用函数索引来影响执行计划;
2. 测试基本环境:
* 硬件:T60笔记本,T2500的CPU,2G内存
* 操作系统:Windows xp
* Oracle版本:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
* 主要的SQL测试在一个app_user表上进行,表格有3,000,000条数据;
* 为消除缓存等各方面的影响,每次要select之前都重启Oracle服务,保证缓存是空的;
3. 测试表格定义和记录数
下面是app_user的定义和记录数,3百万记录数已经具有一定的代表性;
注意:看到红色部分,这里user_id上已经有主键;
hetaoblog@ORCL>SELECT DBMS_METADATA.GET_DDL(‘TABLE’,'APP_USER’,'SCOTT’) FROM DUAL;
DBMS_METADATA.GET_DDL(‘TABLE’,'APP_USER’,'SCOTT’)
——————————————————————————–
CREATE TABLE “SCOTT”.”APP_USER”
( “USER_ID” NUMBER(*,0),
“USER_NAME” VARCHAR2(20),
“GENDER” CHAR(1),
“EMAIL” VARCHAR2(30),
CONSTRAINT “UNIQUE_EMAIL” UNIQUE (“EMAIL”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE “USERS” ENABLE,
CONSTRAINT “UNIQUE_NAME” UNIQUE (“USER_NAME”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE “USERS” ENABLE,
CONSTRAINT “APP_USER_PK” PRIMARY KEY (“USER_ID”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
TABLESPACE “USERS” ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE “USERS” ENABLE ROW MOVEMENT
hetaoblog@ORCL>select count(*) from scott.app_user;
COUNT(*)
———-
3000017
4. 测试SQL和过程
4.1测试SQL为:select * from scott.app_user where abs(user_id) = 100000
4.2 测试用例1【无函数索引】
这时,为避免缓存影响,重启数据库,然后执行下面的查询:
hetaoblog@ORCL>select * from scott.app_user where abs(user_id) = 100000;
USER_ID USER_NAME GENDER EMAIL
———- —————————————- —— ————————————————————
100000 user100000 M user100000@qq.com
已用时间: 00: 00: 09.36
执行计划
———————————————————-
Plan hash value: 2096499096
——————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————
| 0 | SELECT STATEMENT | | 197 | 8865 | 4039 (4)| 00:00:49 |
|* 1 | TABLE ACCESS FULL| APP_USER | 197 | 8865 | 4039 (4)| 00:00:49 |
——————————————————————————
Predicate Information (identified by operation id):
—————————————————
1 – filter(ABS(“USER_ID”)=100000)
Note
—–
– dynamic sampling used for this statement
统计信息
———————————————————-
432 recursive calls
0 db block gets
18021 consistent gets
17879 physical reads
0 redo size
613 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
4.3测试用例2【有函数索引】
下面添加在user_id上的函数索引,对于user_id的abs函数建索引
hetaoblog@ORCL>create index app_user_abs_id on app_user(abs(user_id));
索引已创建。
已用时间: 00: 00: 44.20
添加索引后,重启数据库,再次做查询:
hetaoblog@ORCL>select * from scott.app_user where abs(user_id) = 100000;
USER_ID USER_NAME GENDER EMAIL
———- —————————————- —— ————————————————————
100000 user100000 M user100000@qq.com
已用时间: 00: 00: 00.96
执行计划
———————————————————-
Plan hash value: 319304378
———————————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
———————————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 45 | 76 (2)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| APP_USER | 1 | 45 | 76 (2)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | APP_USER_ABS_ID | 9927 | | 3 (0)| 00:00:01 |
———————————————————————————————–
Predicate Information (identified by operation id):
—————————————————
2 – access(ABS(“USER_ID”)=100000)
Note
—–
– dynamic sampling used for this statement
统计信息
———————————————————-
561 recursive calls
0 db block gets
172 consistent gets
377 physical reads
116 redo size
613 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed
5. 结论分析:
正如Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能的例子一样,对于所测试的app_user表,3百万条记录,对于select * from scott.app_user where abs(user_id) = 100000;这条sql,直接在user_id上建索引对这条SQL的访问是没有时间上的改进的,因为在这样的情况下,本质上B树上存的是user_id的值,而不是abs(user_id)的值,所以Oracle采取了全表扫描的方式来访问数据库。
解决这样问题的方法就是在app_user表上建一个abs(user_id)的函数索引,相当于多了一个虚拟列abs(user_id),然后在这个虚拟列上建索引;可以看到执行计划相差较大,从统计信息分析,IO操作少了很多。
结果对照表:
SQL运行时间 执行计划主要步骤 一致读 物理读
有函数索引 0. 96秒 INDEX RANGE SCAN 172 377
无函数索引 09.36秒 TABLE ACCESS FULL 18021 17879
这里以abs函数做例子,其他函数也是一样的情况,比如upper(),lower(),instr(),length(),substr(),instr(),to_date(),trunc(),to_char()等,当在相关列上有函数调用后,普通的索引并不会发生作用,需要使用函数索引来改变查询计划,提高SQL性能
正如Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能的例子一样,对于所测试的app_user表,3百万条记录,对于select * from scott.app_user where abs(user_id) = 100000;这条sql,直接在user_id上建索引对这条SQL的访问是没有时间上的改进的,因为在这样的情况下,本质上B树上存的是user_id的值,而不是abs(user_id)的值,所以Oracle采取了全表扫描的方式来访问数据库。
解决这样问题的方法就是在app_user表上建一个abs(user_id)的函数索引,相当于多了一个虚拟列abs(user_id),然后在这个虚拟列上建索引;可以看到执行计划相差较大,从统计信息分析,IO操作少了很多。
1. 概要
昨天在Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能说明了索引对select语句的巨大性能提高,今天,来看一种情况,就是在where语句中,在索引列上有函数操作时,普通的索引并不会发生作用,需要使用函数索引来影响执行计划;
2. 测试基本环境:
* 硬件:T60笔记本,T2500的CPU,2G内存
* 操作系统:Windows xp
* Oracle版本:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
* 主要的SQL测试在一个app_user表上进行,表格有3,000,000条数据;
* 为消除缓存等各方面的影响,每次要select之前都重启Oracle服务,保证缓存是空的;
3. 测试表格定义和记录数
下面是app_user的定义和记录数,3百万记录数已经具有一定的代表性;
注意:看到红色部分,这里user_id上已经有主键;
hetaoblog@ORCL>SELECT DBMS_METADATA.GET_DDL(‘TABLE’,'APP_USER’,'SCOTT’) FROM DUAL;
DBMS_METADATA.GET_DDL(‘TABLE’,'APP_USER’,'SCOTT’)
——————————————————————————–
CREATE TABLE “SCOTT”.”APP_USER”
( “USER_ID” NUMBER(*,0),
“USER_NAME” VARCHAR2(20),
“GENDER” CHAR(1),
“EMAIL” VARCHAR2(30),
CONSTRAINT “UNIQUE_EMAIL” UNIQUE (“EMAIL”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE “USERS” ENABLE,
CONSTRAINT “UNIQUE_NAME” UNIQUE (“USER_NAME”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE “USERS” ENABLE,
CONSTRAINT “APP_USER_PK” PRIMARY KEY (“USER_ID”)
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
TABLESPACE “USERS” ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE “USERS” ENABLE ROW MOVEMENT
hetaoblog@ORCL>select count(*) from scott.app_user;
COUNT(*)
———-
3000017
4. 测试SQL和过程
4.1测试SQL为:select * from scott.app_user where abs(user_id) = 100000
4.2 测试用例1【无函数索引】
这时,为避免缓存影响,重启数据库,然后执行下面的查询:
hetaoblog@ORCL>select * from scott.app_user where abs(user_id) = 100000;
USER_ID USER_NAME GENDER EMAIL
———- —————————————- —— ————————————————————
100000 user100000 M user100000@qq.com
已用时间: 00: 00: 09.36
执行计划
———————————————————-
Plan hash value: 2096499096
——————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————
| 0 | SELECT STATEMENT | | 197 | 8865 | 4039 (4)| 00:00:49 |
|* 1 | TABLE ACCESS FULL| APP_USER | 197 | 8865 | 4039 (4)| 00:00:49 |
——————————————————————————
Predicate Information (identified by operation id):
—————————————————
1 – filter(ABS(“USER_ID”)=100000)
Note
—–
– dynamic sampling used for this statement
统计信息
———————————————————-
432 recursive calls
0 db block gets
18021 consistent gets
17879 physical reads
0 redo size
613 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
4.3测试用例2【有函数索引】
下面添加在user_id上的函数索引,对于user_id的abs函数建索引
hetaoblog@ORCL>create index app_user_abs_id on app_user(abs(user_id));
索引已创建。
已用时间: 00: 00: 44.20
添加索引后,重启数据库,再次做查询:
hetaoblog@ORCL>select * from scott.app_user where abs(user_id) = 100000;
USER_ID USER_NAME GENDER EMAIL
———- —————————————- —— ————————————————————
100000 user100000 M user100000@qq.com
已用时间: 00: 00: 00.96
执行计划
———————————————————-
Plan hash value: 319304378
———————————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
———————————————————————————————–
| 0 | SELECT STATEMENT | | 1 | 45 | 76 (2)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| APP_USER | 1 | 45 | 76 (2)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | APP_USER_ABS_ID | 9927 | | 3 (0)| 00:00:01 |
———————————————————————————————–
Predicate Information (identified by operation id):
—————————————————
2 – access(ABS(“USER_ID”)=100000)
Note
—–
– dynamic sampling used for this statement
统计信息
———————————————————-
561 recursive calls
0 db block gets
172 consistent gets
377 physical reads
116 redo size
613 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
1 rows processed
5. 结论分析:
正如Oracle 10g SQL性能优化-使用索引提高数据库select语句的性能的例子一样,对于所测试的app_user表,3百万条记录,对于select * from scott.app_user where abs(user_id) = 100000;这条sql,直接在user_id上建索引对这条SQL的访问是没有时间上的改进的,因为在这样的情况下,本质上B树上存的是user_id的值,而不是abs(user_id)的值,所以Oracle采取了全表扫描的方式来访问数据库。
解决这样问题的方法就是在app_user表上建一个abs(user_id)的函数索引,相当于多了一个虚拟列abs(user_id),然后在这个虚拟列上建索引;可以看到执行计划相差较大,从统计信息分析,IO操作少了很多。
结果对照表:
SQL运行时间 执行计划主要步骤 一致读 物理读
有函数索引 0. 96秒 INDEX RANGE SCAN 172 377
无函数索引 09.36秒 TABLE ACCESS FULL 18021 17879
这里以abs函数做例子,其他函数也是一样的情况,比如upper(),lower(),instr(),length(),substr(),instr(),to_date(),trunc(),to_char()等,当在相关列上有函数调用后,普通的索引并不会发生作用,需要使用函数索引来改变查询计划,提高SQL性能
发表评论
-
mysql 事务机制
2011-04-01 13:52 1685mysql事物机制 一、启动方式 1、使用 serv ... -
ibatis 简单修改ibatis框架
2011-03-31 15:45 974简单修改ibatis框架 使用ibatis框架生成 ... -
mysql 导入导出数据
2011-03-22 15:05 865mysql导入导出数据 1、导入数据 ... -
mysql 修改表结构
2011-03-18 11:50 3894mysql 修改表结构 1.增加一个字段(一列) ... -
mysql 乱码问题
2011-03-16 17:43 910mysql乱码问题。 统一编码,以gbk为例。 ... -
mysql 中文文档
2011-01-27 16:27 1707mysql的中文文档地址: http:/ ... -
mysql 常用指令
2011-01-19 15:21 1192windows 环境变量配置: pah ... -
oracle 卸载与安装三
2010-09-04 17:24 10113 配置(PL/SQL) 3.1 链接本地服务器 ... -
oracle 卸载与安装二
2010-09-04 17:00 12422 Oracle 安装 2.1 Oracle主目录路 ... -
oracle 卸载与安装一
2010-09-04 16:51 1109Oracle 卸载 1 彻底卸载Or ... -
数据库 sql for loop 常用脚本更新数据
2010-08-27 08:49 1477declare i number := 1; ... -
数据库 sql存储过程
2010-08-21 19:04 962create or replace procedure te ... -
数据库 sql游标
2010-08-14 17:57 10741 基本知识 declare 定义游标open 打开游标f ... -
数据库 sql基本语法
2010-08-14 15:04 7021 集合运算符 union all 结合两个select语句结 ... -
数据库 sql需求
2010-08-11 12:55 9021 需求:某人借钱(A表),还钱(B表) 要查询这个人还欠多少 ... -
数据库 sql函数
2010-07-28 08:28 10521 sql函数语法 1.1 条件语句 if else - ... -
Oracle 存储过程
2010-06-22 09:25 1056--1 存储过程迁移数据 CREATE OR RE ... -
数据库 MySql2
2010-05-04 21:10 956数据库 MySql2 -
数据库 MySql1
2010-05-04 21:10 782数据库 MySql1 指令 1 mysql; 2 use ... -
Oracle 注意事项‘’null 空格
2010-04-10 19:59 962sql 空字符串与空格不一样 select ' ' fr ...
相关推荐
主要内容包括:Oracle关系数据库,Oracle数据库体系结构,SQL基本查询,修改SQL数据与SQL*Plus命令,PL/SQL编程基础,用户、模式和表,高级查询,过程、函数和程序包,表类型,索引,视图、序列和同义词,触发器,...
### Oracle性能优化技巧详解 ...综上所述,Oracle性能优化涉及多个方面,包括但不限于优化器的选择、表访问方式、SQL语句的编写和执行等。通过对这些方面的深入了解和合理运用,可以显著提升Oracle数据库的查询性能。
在Oracle数据库优化领域,缓存机制是一项关键的技术手段,旨在通过将频繁访问的数据和对象保留在内存中来提高系统的响应速度和整体性能。本篇文章将深入探讨Oracle数据库中的缓存机制,包括缓存数据和缓存数据库对象...
本文档是关于ORACLE数据库及SQL语言考试题,涵盖了名词解释、ORACLE数据库知识问答和SQL语句编写三部分,旨在考察新同事ORACLE数据库知识和SQL语言掌握情况。 名词解释 1. 数据库:按照数据结构来组织、存储和管理...
数据库优化不仅涉及硬件配置、系统架构设计,更聚焦于SQL查询的优化,以提高数据检索速度和整体系统性能。本文将深入探讨优化数据库的思想以及SQL语句优化的原则。 一、优化数据库的思想 1. 数据库设计:良好的...
本书《精通Oracle.10g.PL/SQL编程》应旨在帮助读者深入理解和掌握在Oracle 10g环境中使用PL/SQL进行高效编程的方法和技巧。 PL/SQL由以下几个核心部分组成: 1. **声明部分**:在这里,你可以声明变量、常量、游标...
- **使用视图**:视图可以像普通表一样被查询,但不能直接修改其中的数据。 ### 9. 索引 - **索引的作用**:提高数据检索速度,类似于书的目录。 - **创建索引**:使用CREATE INDEX语句创建索引。 - **索引类型**...
在本实验中,我们主要探讨了Oracle数据库中的SQL语句应用,涉及到了表、视图、索引以及序列等核心概念。以下是对这些知识点的详细解释: 1. **创建表**: - 使用`CREATE TABLE`语句创建了一个名为`person`的表,...
以上知识点涵盖了ORACLE数据库的基本概念、数据备份与恢复、常用SQL函数、数据表的连接方式以及SQL语句的编写等方面的内容。希望这些知识点能够帮助读者更好地理解和掌握ORACLE数据库及SQL语言的相关知识。
Oracle数据库是世界上最广泛使用的数据库管理系统之一,SQL(Structured Query Language)是访问和操作数据库的标准语言。在本章中,我们将深入探讨SQL开发中的一个重要概念——视图,它是Oracle数据库中的一个重要...
12 管理索引 目标 12-2 索引的分类 12-3 B 树索引 12-4 位图索引 12-6 B 树索引和位图索引的比较 12-7 创建普通 B 树索引 12-8 创建索引:指导 12-10 创建位图索引 12-11 修改索引的储存参数 12-12 分配和回收索引...
SQL优化是数据库性能优化的关键技术之一,本文将详细介绍SQL优化的各种技术和方法。 索引 索引是SQL优化的基础技术之一,索引可以加速查询速度、提高数据检索效率。常见的索引类型有: 1. 普通索引(Normal Index...
选定某一主题,运用oracle数据库,以及相关技术方法设计和开发一个信息管理的数据库系统,实现数据库的开发应用以及日常管理维护等基本功能。 具体要求如下: (1)选定某一主题,创建一个oracle数据库,对其进行...
Oracle 10g的新特性 - **Automatic Storage Management (ASM)**:自动存储管理。 - **Data Guard Broker**:简化Data Guard管理。 - **Database Resource Manager**:资源管理。 - **Database Replay**:性能诊断...
### Oracle数据库面试题知识点解析 #### 一、基础知识(1-20) 1. **Oracle数据库的主要特点**: - **高性能与可扩展性**:支持大量并发用户和大规模数据处理。 - **高可用性**:具备强大的容错能力和故障恢复...
视图和索引是Oracle数据库中两个非常关键的概念,它们对于优化查询性能、管理数据以及提高数据安全性都至关重要。以下是对这两个概念的详细解释: 一、Oracle视图 1. 定义:视图是从一个或多个表中创建的虚拟表,它...