新書推薦:
《
我们为什么会做梦:让梦不再神秘的新科学
》
售價:HK$
79.4
《
算法图解(第2版)
》
售價:HK$
80.3
《
科学的奇幻之旅
》
售價:HK$
79.4
《
画艺循谱:晚明的画谱与消闲
》
售價:HK$
147.2
《
新民说·现实政治史:从马基雅维利到基辛格
》
售價:HK$
102.4
《
宽容是件奢侈品(人生360度·一分钟经典故事)
》
售價:HK$
45.8
《
甲骨拼合六集
》
售價:HK$
342.7
《
视觉美食家:商业摄影实战与创意解析
》
售價:HK$
135.7
編輯推薦:
Oracle泰斗、性能调整大师理查德?尼米克力作,国内Oracle一线调优专家精心翻译,涵盖11gR2版数据库和Exadata等最新的热门话题,助你成为顶尖的Oracle调优专家
內容簡介:
在Oracle认证大师Richard Niemiec的帮助下,系统地识别和排除数据库的性能问题:《Oracle Database 11g R2性能调整与优化》一书详细介绍了最新的监控、故障排除和优化的方法,取自真实世界的案例研究和最佳实践遍及全书,从中您可以学会如何找出和解决瓶颈问题、如何配置存储设备、如何有效运行查询以及如何开发无错误的 SQL和PLSQL代码。由Oracle出版社出版的这部书中还介绍了有关测试、报表和安全功能等方面的改进。
主要内容
● 正确运用 Oracle 11g R2数据库的索引和分区技术
● 运用V$视图和X$表来紧急处理数据库问题
● 使用Oracle Exadata和Oracle Exalogic弹性云
● 运用Oracle RAT来分布工作负载
● 有效地管理磁盘驱动器、磁盘阵列和内存
● 运用Oracle的Statspack和AWR等工具来生成报告
● 运用Oracle的SQL提示和TRACE实用工具来优化查询
● 运用sar、vmstat和iostat来监控系统统计信息
關於作者:
Richard Niemiec是全球知名的IT专家,是Oracle ACE总监和全世界最早获得“Oracle认证大师”荣誉的六泰斗之一。
在过去的30年里,他为弘扬Oracle技术而积极发表演说,并屡屡被评为最佳演讲人:Oracle合作者全球用户大会最佳演讲人6次,中西部用户大会最佳演讲人10次和Oracle全球大会最佳演讲人。
过去的25年间,他为很多名列财富500强的客户设计了系统架构并实施了优化,这些客户中包括ACT、玛氏公司、麦当劳、诺基亚、NavteqMapQuest、密西根大学、AT&T和百事可乐。他既可以开展教学又可以提供咨询,在执行方向、数据库管理和架构、性能优化、项目管理和技术训练等方面的经验尤为丰富。
目錄 :
"第1章 11g R1 R2新特性介绍针对DBA和开发者 1br
1.1 轮到Exadata出场了! 3br
1.2 高级压缩 6br
1.3 自动诊断信息库Automatic Diagnostic Repository,ADR 7br
1.4 自动共享内存管理Automatic Shared Memory Management,ASMM的改进 8br
1.5 ASM的改进 9br
1.5.1 从ASM首选镜像读取 10br
1.5.2 滚动升级打补丁 10br
1.5.3 更快的重新平衡 11br
1.5.4 ASM磁盘组兼容性 11br
1.5.5 ASMCMD命令扩展 12br
1.6 自动SQL优化 12br
1.7 数据卫士的增强 13br
1.7.1 快照备用Snapshot Standby 14br
1.7.2 活动数据卫士 14br
1.7.3 混合平台支持 15br
1.7.4 高级压缩支持逻辑备用数据库11gR2 15br
1.7.5 透明数据加密支持逻辑备用数据库 15br
1.7.6 增强的数据泵压缩 15br
1.7.7 数据泵加密Dump文件集 16br
1.7.8 数据泵的传统模式 16br
1.8 增强了的统计信息 16br
1.8.1 增强了的IO统计信息 16br
1.8.2 减少收集分区对象的统计信息 16br
1.8.3 待定统计信息 17br
1.8.4 多列统计信息 17br
1.8.5 表达式统计信息 17br
1.9 闪回数据归档Flashback Data Archive,FBDA 18br
1.10 健康监控器Health Monitor 18br
1.11 事件打包服务Incident Packaging Service,IPS 21br
1.12 不可视索引invisible index 22br
1.13 分区新特性 22br
1.13.1 区间分区 23br
1.13.2 REF分区 23br
1.13.3 系统分区 25br
1.13.4 虚拟列分区 26br
1.13.5 分区顾问 26br
1.14 只读表 26br
1.15 RAC One Node和RAC Patching 27br
1.16 真正应用测试Real Application Testing,RAT 28br
1.17 SQL性能分析器SQL Performance Analyzer,SPA 29br
1.18 结果集缓存Result Cache 29br
1.19 RMAN的新特性 30br
1.19.1 备份的优化 30br
1.19.2 长期备份处理的改进 30br
1.19.3 并行备份巨大的数据文件 30br
1.19.4 更快的备份压缩改进的压缩 31br
1.19.5 活动数据库复制Active Database Duplication 31br
1.19.6 更好的恢复目录管理 32br
1.19.7 增强的归档日志删除策略 32br
1.19.8 数据恢复顾问Data Recovery Advisor 32br
1.19.9 虚拟专用目录 35br
1.19.10 主动的健康检查 36br
1.19.11 块恢复闪回日志 37br
1.19.12 块恢复物理备用 37br
1.20 安全文件 37br
1.20.1 压缩 38br
1.20.2 加密 38br
1.20.3 重复数据删除 38br
1.21 流GoldenGate是流的未来的增强 40br
1.21.1 XStream In 40br
1.21.2 XStream Out 40br
1.21.3 流支持高级压缩11gR2 40br
1.22 临时表空间的收缩 40br
1.23 透明数据加密TDE的改进 41br
1.24 11g新的后台进程 41br
1.25 版本对照表 42br
1.26 新特性回顾 47br
1.27 参考文献 48br
第2章 索引基本原理针对DBA和初级开发人员 49br
2.1 索引基本概念 50br
2.2 不可视索引 52br
2.3 组合索引 55br
2.4 索引抑制 56br
2.4.1 使用不等于运算符、!= 56br
2.4.2 使用IS NULL或IS NOT NULL 57br
2.4.3 使用LIKE 58br
2.4.4 使用函数 59br
2.4.5 比较不匹配的数据类型 59br
2.5 选择性 60br
2.6 集群因子 60br
2.7 二元高度Binary Height 61br
2.8 使用直方图 64br
2.9 快速全扫描 65br
2.10 跳跃式扫描 66br
2.11 索引的类型 67br
2.11.1 B树索引 67br
2.11.2 位图索引 68br
2.11.3 哈希索引 70br
2.11.4 索引组织表 71br
2.11.5 反键索引 71br
2.11.6 基于函数的索引 72br
2.11.7 分区索引 73br
2.11.8 位图连接索引 75br
2.12 快速重建索引 76br
2.13 在线重建索引 76br
2.14 要诀回顾 77br
2.15 参考文献 78br
第3章 磁盘安装启用的方法和ASM针对DBA 81br
3.1 磁盘阵列:必然之选 82br
3.1.1 使用磁盘阵列改进性能和可用性 82br
3.1.2 所需的磁盘数量 83br
3.1.3 可用的RAID级别 83br
3.1.4 更新的RAID 5 84br
3.2 传统文件系统的安装和维护 85br
3.3 在硬件磁盘之间分布关键数据文件 85br
3.3.1 分开存储数据和索引文件 86br
3.3.2 避免IO磁盘争用 87br
3.3.3 通过移动数据文件来均衡文件IO 88br
3.4 本地管理的表空间 89br
3.4.1 创建本地管理的表空间 89br
3.4.2 把字典管理的表空间迁移到本地管理的表空间 90br
3.4.3 Oracle大文件表空间 90br
3.4.4 Oracle管理文件 91br
3.5 ASM简介 92br
3.5.1 IT部门内各个角色之间的沟通 93br
3.5.2 ASM实例 93br
3.5.3 ASM初始化参数 95br
3.5.4 ASM的安装 95br
3.5.5 ASM初始化参数和SGA调整 96br
3.5.6 ASM和权限 96br
3.5.7 ASM磁盘 97br
3.5.8 ASM和多路径 99br
3.5.9 ASM磁盘组 99br
3.5.10 ASM磁盘组和数据库 101br
3.5.11 ASM冗余和故障组 102br
3.5.12 新的空间相关列 103br
3.5.13 集群同步服务 104br
3.5.14 数据库实例和ASM 105br
3.5.15 使用ASM进行数据库整合和集群化 105br
3.5.16 支持ASM的数据库进程 106br
3.5.17 大文件和ASM 106br
3.5.18 支持ASM的数据库初始化参数 107br
3.5.19 ASM和数据库部署最佳实践 107br
3.5.20 ASM存储管理和分配 108br
3.5.21 ASM重新平衡和重新分布 108br
3.6 使用分区来避免磁盘争用 110br
3.6.1 获得关于分区的更多信息 112br
3.6.2 其他类型的分区 112br
3.6.3 Oracle 11gR2的新分区选项 115br
3.6.4 其他分区选项 117br
3.7 使用索引分区 119br
3.8 导出分区 120br
3.9 消除碎片 120br
3.9.1 使用正确的区大小 121br
3.9.2 创建新的表空间并把数据移到其中 121br
3.9.3 导出和重新导入表 123br
3.9.4 正确设定PCTFREE以避免链化Chaining现象 123br
3.9.5 重建数据库 125br
3.10 增加日志文件尺寸和LOG_CHECKPOINT_ INTERVAL以提高速度 125br
3.10.1 确定重做日志文件的大小是否存在问题 126br
3.10.2 确定日志文件的大小和检查点的时间间隔 126br
3.11 快速恢复区Fast Recovery Area,FRA 128br
3.12 增加恢复的可能性:在每次批处理后提交 129br
3.12.1 把大的事务隔离到它们自己的回滚段上 129br
3.12.2 使用UNDO表空间 130br
3.12.3 监控UNDO空间 131br
3.12.4 结束有问题的会话 131br
3.13 在不同磁盘和控制器上存放多个控制文件 132br
3.14 磁盘IO的其他注意事项和提示 133br
3.15 设计阶段需要注意的问题 133br
3.16 要诀回顾 134br
3.17 参考文献 135br
第4章 通过初始化参数调优数据库针对DBA 137br
4.1 升级到Oracle 11gR2之后 138br
4.2 识别重要的初始化参数 141br
4.3 在不重启数据库的情况下修改初始化参数 143br
4.4 通过Oracle实用程序洞察初始化参数 149br
4.5 用企业管理器查看初始化参数 150br
4.6 优化DB_CACHE_SIZE来提高性能 151br
4.6.1 使用V$DB_CACHE_ADVICE优化DB_CACHE_SIZE 153br
4.6.2 保持数据缓存命中率超过95% 153br
4.6.3 监控V$SQLAREA视图以查找较慢的查询 153br
4.7 设定DB_BLOCK_SIZE来反映数据读的大小 156br
4.8 把SGA_MAX_SIZE设置为主内存大小的25%到50% 157br
4.9 优化SHARED_POOL_SIZE以获取最佳性能 158br
4.9.1 使用存储过程来优化共享SQL区域的使用 158br
4.9.2 设定足够大的SHARED_POOL_SIZE以保证充分利用DB_CACHE_SIZE 160br
4.9.3 保证数据字典缓存命中率至少为95% 160br
4.9.4 保证库缓存的重载率为0,并使命中率在95%以上 161br
4.9.5 使用可用内存来判断SHARED_POOL_SIZE是否设置正确 164br
4.9.6 使用X$KSMSP表详细观察共享池 164br
4.9.7 关于缓存大小需要记住的要点 165br
4.9.8 与初始化参数相关的等待 166br
4.10 在Oracle中使用多个缓冲池 167br
4.10.1 与DB_CACHE_SIZE相关并为数据分配内存的池 167br
4.10.2 修改LRU算法 168br
4.10.3 与SHARED_POOL_SIZE相关并为语句分配内存的池 168br
4.11 调整PGA_AGGREGATE_TARGET以优化内存的使用 169br
4.12 修改SGA大小以避免换页Paging和交换Swapping 170br
4.13 了解Oracle优化器 170br
4.14 创建足够的调度程序Dispatcher 171br
4.14.1 足够的打开的游标OPEN_CURSORS 172br
4.14.2 不要让DDL语句失败使用DDL锁超时机制 172br
4.15 两个重要的Exadata初始化参数仅针对Exadata 172br
4.16 25个需要深思熟虑的重要初始化参数 173br
4.16.1 历年的初始化参数 175br
4.16.2 查找未公开的初始化参数 176br
4.17 理解典型的服务器 176br
4.17.1 典型服务器的建模 177br
4.17.2 Oracle Application数据库选型 178br
4.18 要诀回顾 179br
4.19 参考文献 180br
第5章 企业管理器和网格控制器针对DBA和开发人员 183br
5.1 企业管理器EM基础 185br
5.2 从All Targets和其他分组开始 187br
5.3 SQL性能分析器SPA 188br
5.4 ADDM 191br
5.4.1 “数据库实例服务器”选项卡和“数据库管理”选项卡 196br
5.4.2 “数据库实例服务器”选项卡:表空间 197br
5.4.3 “数据库实例服务器”选项卡:聚焦实例级别 198br
5.4.4 “数据库实例服务器”选项卡:所有初始化参数 199br
5.4.5 “数据库实例服务器”选项卡:管理优化器统计 200br
5.4.6 “数据库实例服务器”选项卡:资源管理器消费者组 202br
5.4.7 “数据库维护”选项卡 203br
5.4.8 “数据库拓扑”选项卡 203br
5.4.9 “数据库性能”选项卡 204br
5.5 监控主机 211br
5.6 监控应用服务器 213br
5.7 监控Web应用程序 216br
5.8 SQL顾问SQL Advisors 218br
5.9 Deployments选项卡补丁选项 219br
5.10 调度中心和Jobs选项卡 220br
5.11 Reports选项卡 221br
5.12 ASM自动存储管理的性能 223br
5.13 真正应用测试数据库回放 225br
5.14 Exadata的企业管理器 226br
5.15 小结 227br
5.16 要诀回顾 228br
5.17 参考文献 228br
第6章 使用EXPLAIN PLAN和SQL计划管理针对开发人员和DBA 229br
6.1 Oracle的SQL跟踪SQL Trace实用工具 230br
6.1.1 对简单查询使用SQL跟踪的简单步骤 230br
6.1.2 TRACE输出部分 234br
6.1.3 深入探讨TKPROF输出 236br
6.2 使用DBMS_MONITOR 238br
6.3 单独使用EXPLAIN PLAN 242br
6.3.1 EXPLAIN PLAN自顶而下还是从下往上读 245br
6.3.2 EXPLAIN PLAN的另一种输出方法:构建树结构 250br
6.3.3 使用执行树的另一个例子 251br
6.3.4 在开发者产品中利用跟踪EXPLAIN发现有问题的查询 254br
6.3.5 PLAN_TABLE表中的重要列 254br
6.3.6 未公开的跟踪初始化参数 255br
6.4 使用STORED OUTLINES存储纲要 257br
6.5 使用SPM 11g新特性 259br
6.6 要诀回顾 267br
6.7 参考文献 269br
第7章 基本的提示语法针对开发人员和DBA 271br
7.1 最常用的提示 272br
7.1.1 慎用提示 273br
7.1.2 首先修正设计方案 273br
7.2 可用提示及归类 274br
7.2.1 执行路径提示 274br
7.2.2 访问方法提示 275br
7.2.3 查询转换提示 275br
7.2.4 连接操作提示 275br
7.2.5 并行执行提示 276br
7.2.6 其他提示 276br
7.3 指定提示 276br
7.4 指定多个提示 278br
7.5 使用别名时,提示别名而非表名 278br
7.6 提示 278br
7.6.1 Oracle的演示样板:HR方案 279br
7.6.2 FIRST_ROWS提示 279br
7.6.3 ALL_ROWS提示 280br
7.6.4 FULL提示 280br
7.6.5 INDEX提示 281br
7.6.6 NO_INDEX提示 282br
7.6.7 INDEX_JOIN提示 283br
7.6.8 INDEX_COMBINE提示 284br
7.6.9 INDEX_ASC提示 284br
7.6.10 INDEX_DESC提示 285br
7.6.11 INDEX_FFS提示 285br
7.6.12 ORDERED提示 286br
7.6.13 LEADING提示 287br
7.6.14 NO_EXPAND提示 287br
7.6.15 DRIVING_SITE提示 288br
7.6.16 USE_MERGE提示 289br
7.6.17 USE_NL提示 290br
7.6.18 USE_HASH提示 291br
7.6.19 QB_NAME提示 292br
7.6.20 PUSH_SUBQ提示 292br
7.6.21 PARALLEL提示 293br
7.6.22 NO_PARALLEL提示 294br
7.6.23 PARALLEL_INDEX提示 294br
7.6.24 PQ_DISTRIBUTE提示 295br
7.6.25 APPEND提示 296br
7.6.26 NOAPPEND提示 296br
7.6.27 CACHE提示 297br
7.6.28 NOCACHE提示 297br
7.6.29 RESULT_CACHE提示 298br
7.6.30 CURSOR_SHARING_EXACT提示 298br
7.7 杂项提示及注意事项 299br
7.7.1 未公开的提示 300br
7.7.2 如何在视图中使用提示 301br
7.7.3 关于提示和STORED OUTLINES11g中的SPM的注意事项 301br
7.8 提示为什么不起作用 302br
7.9 提示一览 302br
7.10 要诀回顾 303br
7.11 参考文献 305br
第8章 查询优化针对开发人员和初级DBA 307br
8.1 应该优化哪些查询?查询V$SQLAREA和V$SQL视图 308br
8.1.1 从V$SQLAREA视图中选出最糟糕的查询 308br
8.1.2 从V$SQL视图中选出最糟糕的查询 310br
8.2 使用Oracle 11g视图定位占用大量资源的会话和查询 311br
8.2.1 从V$SESSMETRIC视图中选出当前最占用资源的会话 311br
8.2.2 查看可用的AWR快照 312br
8.2.3 从DBA_HIST_SQLSTAT视图中发现最糟糕的查询 312br
8.2.4 从DBA_HIST_SQLSTAT视图中选择查询文本 313br
8.2.5 从DBA_HIST_SQL_PLAN视图中选出查询EXPLAIN PLAN 314br
8.3 何时应该使用索引 315br
8.4 忘记了索引怎么办 316br
8.4.1 建立索引 316br
8.4.2 不可视索引invisible index 317br
8.4.3 查看表上的索引 317br
8.4.4 在列上正确建立索引了吗? 318br
8.5 建立了差的索引怎么办 318br
8.6 删除索引时保持谨慎 321br
8.7 在SELECT和WHERE子句中的列上建立索引 321br
8.8 使用索引快速全扫描 323br
8.9 使查询“魔术”般加速 325br
8.10 在内存中缓存表 326br
8.11 使用11g新引入的结果集缓存Result Cache 327br
8.12 在多个索引间选择使用选择性最佳的索引 328br
8.13 索引合并 329br
8.14 可能被抑制的索引 331br
8.15 基于函数的索引 333br
8.16 虚拟列Virtual Column 334br
8.17 “古怪”的OR 334br
8.18 使用EXISTS函数和嵌套子查询 336br
8.19 表就是视图 337br
8.20 SQL和“大一统”理论 337br
8.21 Oracle Database 11g中的优化变化 337br
8.22 Oracle 11g自动SQL优化 338br
8.22.1 保证执行优化操作的用户能访问API 338br
8.22.2 创建优化任务 338br
8.22.3 确定从顾问日志中可以查看到任务 339br
8.22.4 执行SQL优化任务 339br
8.22.5 查看优化任务的状态 339br
8.22.6 显示SQL优化顾问生成的报告 340br
8.22.7 检查报告输出 340br
8.23 使用SQL优化顾问自动优化SQL语句 342br
8.23.1 启用自动SQL优化顾问 342br
8.23.2 配置自动SQL优化顾问 343br
8.23.3 查看自动SQL优化的结果 343br
8.24 使用SPA 347br
8.25 要诀回顾 352br
8.26 参考文献 353br
第9章 表连接和其他高级优化针对高级DBA和开发人员 355br
9.1 RAT 357br
9.2 SPA 362br
9.2.1 创建SQL优化集 363br
9.2.2 创建分析任务 363br
9.2.3 执行分析任务 364br
9.2.4 查询性能分析的顾问任务 365br
9.2.5 取消正在执行的SPA分析任务 365br
9.2.6 删除SPA分析任务 365br
9.2.7 确定活动的SQL优化集 365br
9.2.8 删除SQL优化集引用 366br
9.2.9 删除SQL优化集 366br
9.3 连接方法 367br
9.3.1 嵌套循环连接 367br
9.3.2 排序合并连接 368br
9.3.3 集群连接 369br>
內容試閱 :
2.1 索引基本概念
当访问表中数据时,Oracle提供了两种方式:从表中读取所有行即全表扫描,或者通过ROWID一次读取一行。当访问大数据量表中的少量行时,您可能想使用索引。例如,如果只访问大数据量表中5%的行,并且可以使用索引标识需要读取的数据块,这样花费的IO较少。如果没有使用索引,就要读取表中所有的数据块。
索引对性能改进的程度取决于数据的选择性以及数据在表的数据块中的分布方式。如果数据选择性很好,那么表中将只有很少的行匹配一个索引值例如护照号码。Oracle将能够快速查询索引,找到匹配索引值的ROWID,从而快速查到表中相应的少量数据块。如果数据选择性不好例如国家名,那么对一个值索引可能返回许多ROWID,导致从表中查询许多不连续的数据块。
如果数据选择性很好,但是相关的行在表中的物理存储位置并不互相靠近,这种情况下,索引带来的好处就会大打折扣。如果匹配索引值的数据分散在表的多个数据块中,就必须从表中把每个数据块都选出来以得到需要的查询结果。在一些情况下,您会发现当数据分散在表的多个数据块中时,最好是不使用索引,而是选择全表扫描。执行全表扫描时,Oracle使用多块读取以快速扫描表。基于索引的读是单块读,因此在使用索引时的目标是减少完成查询所需的单块读的数量。
通过对Oracle一些可用选项的利用,比如分区、并行DML、并行查询以及调整db_file_multiblock_read_count进行更大的IO操作,全表扫描和索引查找之间的平衡点正发生着改变。硬件更为快速,可以在磁盘的高速缓存中缓存更多的信息,内存也变得更为廉价。与此同时,Oracle已经增强的索引特性,包括了跳跃式扫描索引和其他内部操作用来减少返回数据所需的时间。
要诀
当升级Oracle版本时,确保测试应用程序中的查询以确定查询的执行路径是否仍然使用在升级之前使用的索引。看看执行计划是否改变,这种改变的效果是变得更好还是变得更差。
一般来说,索引能提高查询的性能。SELECT语句、UPDATE和DELETE命令的WHERE子句的性能当访问的行较少时可以借助索引获得提高。一般来说,增加索引会降低INSERT语句的性能因为需要同时对表和索引进行操作。索引列上的UPDATE操作将会比没有加索引慢很多,因为数据库必须管理对表和索引的改动。此外,大量行的DELETE操作将会由于表中存在索引而变慢。
一条删除表中一半数据的DELETE语句同时需要删除所有这些行对应的索引这种情况是非常耗时的。通常说来,在表上加一个索引都会使该表上INSERT操作的执行时间变成原来的三倍;再加一个索引就会再慢一倍;然而,一个由两列组成的索引并不比只有一个列的索引差很多。索引列的UPDATE和DELETE操作同样也会变慢。您需要平衡索引带来的查询性能的提升和对数据修改性能的影响。
通过查询DBA_INDEXES视图可获得一个表上所有索引的清单,也可以通过访问USER_ INDEXES视图查询当前方案schema的索引。查询ALL_INDEXES视图可以查看能够访问的所有表的索引。
例如,在一张随着Oracle产品一起提供的演示表emp上创建了两个索引。您可以对任何版本的演示表测试下面的查询:
create index emp_id1 on empempno, ename, deptno;
create index emp_id2 on emp sal;
当执行这些命令时,数据库将在emp表上创建两个单独的索引。每个索引将包含emp表中的特定值以及匹配这些值的行的ROWID。如果需要查找sal值为1000的emp表中的记录,优化器就会使用emp_id2索引查找该值,并找到相关的ROWID,接着使用该ROWID在表中查找对应的行。
下面对USER_INDEXES的查询显示了emp表上新建的索引:
select table_name, index_name
from user_indexes
where table_name = ''EMP'' ;
TABLE_NAME INDEX_NAME
------------------------------ ------------------------------
EMP EMP_ID1
EMP EMP_ID2
输出显示有两个索引,但是没有显示每个索引中包含的列。为了获得当前用户的表中被索引的列的信息,可查询USER_IND_COLUMNS视图;DBA 可以通过访问DBA_IND_COLUMNS视图检索所有方案中被索引的列,而通过ALL_IND_COLUMNS视图则可以查看当前用户有权看到的所有表的被索引列。下面的例子就是通过USER_IND_COLUMNS视图获得当前用户的表中被索引的列的信息:
column index_name format a12
column column_name format a8
column table_name format a8
select table_name, index_name, column_name, column_position
from user_ind_columns
order by table_name, index_name, column_position;
TABLE_NA INDEX_NAME COLUMN_N COLUMN_POSITION
-------- ------------ -------- ---------------
EMP EMP_ID1 EMPNO 1
EMP EMP_ID1 ENAME 2
EMP EMP_ID1 DEPTNO 3
EMP EMP_ID2 SAL 1
emp表中有两个索引。第一个emp_id1是一个组合索引,它对empno、ename和deptno这几列进行索引;第二个索引emp_id2只对sal列进行索引。程序清单中的COLUMN_POSITION字段显示了组合索引中列的顺序,在本例中,按照empno、ename和deptno的顺序。
要诀
查询DBA_INDEXES和DBA_IND_COLUMNS可以检索到一个给定表的索引列表。对于当前用户的方案schema中的索引信息,只能使用USER_INDEXES和USER_IND_COLUMNS来查看。
2.2 不可视索引
决定对哪些列建立索引往往是很难的。主键是被自动索引的,外键也应该被索引,接下来怎么办?更困难的是决定删除某个可能不好的索引。每插入一条记录时,所有索引都必须更新。如果一个被索引的列被更新,该索引也要被更新。在不引起用户查询出现一系列全表扫描或笛卡儿连接的情况下,决定哪些索引需要被删除是很困难的,尤其是在需要调优的第三方应用程序代码不能改变的情况下。不可视索引是该问题一个可能的解决方案。Oracle允许您关闭索引使其不可见,但是索引上的维护工作还会继续在任何DML操作INSERTUPDATEDELETE期间,因为您可能需要快速重新打开它。你可以通过下面的方法使索引可见或不可见:
ALTER INDEX idx1 INVISIBLE;
ALTER INDEX idx1 VISIBLE;
CREATE INDEX . . . INVISIBLE;
下面的查询显示在表emp的deptno列上新建一个不可视索引,在接下来的查询中,我们看不到那个索引:
create index dept_rich_inv_idx on dept_richdeptno invisible;
Index created.
select count*
from dept_rich
where deptno = 30;索引不可见
COUNT*
--------------
512
Execution Plan
----------------------------------------------------------
Plan hash value: 3024595593
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost %CPU | Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 0 | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL | DEPT_RICH | 512 | 1024 | 4 0 | 0:00:01 |
--------------------------------------------------------------------------------
仍然可以使用提示来强制这个索引的使用,在11gR2以前,可以使用INDEX提示,在11gR2中,可以使用USE_INVISIBLE_INDEXES提示,或者把初始化参数OPTIMIZER_USE_INVISIBLE_ INDEXES设置成true详见附录A:
select *+ USE_INVISIBLE_INDEXES * count*
from dept_rich
where deptno = 30;通过提示强制使用索引
COUNT*
--------
512
Execution Plan
----------------------------------------------------------
Plan hash value: 3699452051
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost %CPU| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 1 0 | 00:00:01|
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | INDEX RANGE SCAN| DEPT_RICH_INV_IDX | 512 | 1024 | 1 0 | 00:00:01|
-----------------------------------------------------------------------------------
如果把索引设成可见,就不需要INDEX提示了:
alter index dept_rich_inv_idx visible;
Index altered.
select count*
from dept_rich
where deptno = 30;索引可见
COUNT*
--------
512
Execution Plan
----------------------------------------------------------
Plan hash value: 3699452051
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost %CPU| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 1 0 | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | INDEX RANGE SCAN| DEPT_RICH_INV_IDX | 512 | 1024 | 1 0 | 00:00:01 |
-----------------------------------------------------------------------------------
在不将其变成不可见的前提下,也可以使用NO_INDEX提示来关闭一个索引,看看除此之外是否还使用其他索引或者不使用索引。换句话说,使用除了NO_INDEX中指定的索引之外的任何索引,下面是一个例子:
select *+ no_indexdept_rich dept_rich_inv_idx * count*
from dept_rich
where deptno = 30; 强制不使用带提示的索引
COUNT*
--------
512
Execution Plan
----------------------------------------------------------
Plan hash value: 3024595593
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost %CPU| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 0 | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL | DEPT_RICH | 512 | 1024 | 4 0 | 0:00:01 |
--------------------------------------------------------------------------------
可以随时将这个索引设成不可见:
alter index dept_rich_inv_idx invisible;
Index altered.
可以通过USER_INDEXES或DBA_INDEXES视图来查看索引的可见性:
select index_name, visibility
from dba_indexes 或使用USER_INDEXES
where index_name = ''DEPT_RICH_INV_IDX'';
INDEX_NAME VISIBILITY
-------------------------------- ------------------
DEPT_RICH_INV_IDX INVISIBLE
要诀
通过使用不可视索引,您可以通过使索引不可见的方法,临时“关闭”它们来查看查询在没有它们时的性能。由于不可视索引依然被维护,因此如果有需要的话,可以轻易地把它们“打开”,也就是使它们可见。
2.3 组合索引
当某个索引包含多个列时,我们称这个索引为“组合索引”或“复合索引”composite index。Oracle 9i引入的索引跳跃式扫描增加了优化器在使用组合索引时的选择,所以您在选择索引中的列顺序时应该谨慎。一般来说,索引的第一列应该是最有可能在WHERE 子句中使用的列,并且也是索引中最具选择性的列。
在引入跳跃式扫描功能之前,只有当索引中的前导列也出现在WHERE子句中时,查询才能使用索引。考虑如下程序清单中的示例,其中表emp有一个在列empno、ename和deptno上的组合索引。注意第一部分是empno,第二部分则是ename,第三部分是deptno。如果没有跳跃式扫描功能,除非在WHERE子句中使用前导列empno,否则Oracle一般不会使用这个索引。
select job, empno
from emp
where ename = ''RICH'';
因为ename不是索引的前导列,优化器可能不会选择使用该索引。随着在Oracle 9i中引入跳跃式扫描功能,即使在WHERE子句中没有指定empno值,优化器也可能会选择使用该索引。另外,优化器也可能会选择索引快速全扫描Index Fast Full Scan或全表扫描。
如果在WHERE 子句中使用索引的第三列,也会产生相同的情况:
select job, empno
from emp
where deptno = 30;
该例中,WHERE子句指定了索引中第三列的值,优化器可能选择使用索引跳跃式扫描、索引快速全扫描或全表扫描。创建这个索引时,您就为数据库在执行查询时提供更多的选择,从而有希望改进整体的性能。注意,用户的代码没有改变,但是优化器可以识别该索引,并且根据每种可行方法的预期成本作出决定。
在下面的示例中,使用了索引的一部分。前导列empno用作WHERE 子句中的限制条件,以便Oracle可以使用该索引。
select job, empno
from emp
where empno = ''RICH'';
两种最常见的索引扫描方式是唯一扫描Unique Scan和范围扫描Range Scan。在唯一扫描中,数据库知道索引包含的每一个值都是唯一的。在范围扫描中,数据库将根据查询条件从索引中返回多个符合条件的值。在该例中,emp_id1和emp_id2索引都不是唯一索引。Oracle在返回数据的时候将使用范围扫描。使用CREATE UNIQUE INDEX命令可以创建唯一索引。
在创建主键约束或唯一性约束时,Oracle 将基于指定的列自动创建唯一索引除非使用DISABLE子句创建约束。如果创建多列的主键,Oracle 将创建组合索引,其中的列的排列顺序和创建主键时指定的列的顺序一致。
类似于在列emp_id1 和emp_id2上的索引,Oracle 具备通过每行的ROWID访问单行数据的能力。ROWID 其实就是直接指向单行的物理位置的指针。
要诀
避免将Oracle的ROWID硬编码到特定代码里。因为在不同版本的Oracle中,ROWID结构会有所不同,而且在将来的版本里可能还会有所改变。建议不要对ROWID进行硬编码。