然后现在有q个询问,每次月瓦尔特大叔月季想问一共有多少对pair,满足a+a>=k

Https是什么?
Https是基于安全目的的Http通道,其安全基础由SSL层来保证。最初由netscape公司研发,主要提供了通讯双方的身份认证和加密通信方法。现在广泛应用于互联网上安全敏感通讯。
Https与Http主要区别
协议基础不同:Https在Http下加入了SSL层,
通讯方式不同:Https在数据通信之前需要客户端、服务器进行握手(身份认证),建立连接后,传输数据经过加密,通信端口443。
Http传输数据不加密,明文,通信端口80。
SSL协议基础
SSL协议位于TCP/IP协议与各种应用层协议之间,本身又分为两层:
SSL记录协议(SSL Record Protocol):建立在可靠传输层协议(TCP)之上,为上层协议提供数据封装、压缩、加密等基本功能。
SSL握手协议(SSL Handshake Procotol):在SSL记录协议之上,用于实际数据传输前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL协议通信过程
(1) 浏览器发送一个连接请求给服务器;服务器将自己的证书(包含服务器公钥S_PuKey)、对称加密算法种类及其他相关信息返回客户端;
(2) 客户端浏览器检查服务器传送到CA证书是否由自己信赖的CA中心签发。若是,执行4步;否则,给客户一个警告信息:询问是否继续访问。
(3) 客户端浏览器比较证书里的信息,如证书有效期、服务器域名和公钥S_PK,与服务器传回的信息是否一致,如果一致,则浏览器完成对服务器的身份认证。
(4) 服务器要求客户端发送客户端证书(包含客户端公钥C_PuKey)、支持的对称加密方案及其他相关信息。收到后,服务器进行相同的身份认证,若没有通过验证,则拒绝连接;
(5) 服务器根据客户端浏览器发送到密码种类,选择一种加密程度最高的方案,用客户端公钥C_PuKey加密后通知到浏览器;
(6) 客户端通过私钥C_PrKey解密后,得知服务器选择的加密方案,并选择一个通话密钥key,接着用服务器公钥S_PuKey加密后发送给服务器;
(7) 服务器接收到的浏览器传送到消息,用私钥S_PrKey解密,获得通话密钥key。
(8) 接下来的数据传输都使用该对称密钥key进行加密。
上面所述的是双向认证 SSL 协议的具体通讯过程,服务器和用户双方必须都有证书。由此可见,SSL协议是通过非对称密钥机制保证双方身份认证,并完成建立连接,在实际数据通信时通过对称密钥机制保障数据安全性
1. CouchDB •所用语言: Erlang •特点:DB一致性,易于使用 •使用许可: Apache •协议: HTTP/REST •双向数据复制, •持续进行或临时处理, •处理时带冲突检查, •因此,采用的是master-master复制(见编注2) •MVCC – 写操作不阻塞读操作 •可保存文件之前的版本 •Crash-only(可靠的)设计 •需要不时地进行数据压缩 •视图:嵌入式 映射/减少 •格式化视图:列表显示 •支持进行服务器端文档验证 •支持认证 •根据变化实时更新 •支持附件处理 •因此, CouchApps(独立的 js应用程序) •需要 jQuery程序库 最佳应用场景:适用于数据变化较少,执行预定义查询,进行数据统计的应用程序。适用于需要提供数据版本支持的应用程序。 例如: CRM、CMS系统。 master-master复制对于多站点部署是非常有用的。 (编注2:master-master复制:是一种数据库同步方法,允许数据在一组计算机之间共享数据,并且可以通过小组中任意成员在组内进行数据更新。) 2. Redis •所用语言:C/C++ •特点:运行异常快 •使用许可: BSD •协议:类 Telnet •有硬盘存储支持的内存数据库, •但自2.0版本以后可以将数据交换到硬盘(注意, 2.4以后版本不支持该特性!) •Master-slave复制(见编注3) •虽然采用简单数据或以键值索引的哈希表,但也支持复杂操作,例如 ZREVRANGEBYSCORE。 •INCR & co (适合计算极限值或统计数据) •支持 sets(同时也支持 union/diff/inter) •支持列表(同时也支持队列;阻塞式 pop操作) •支持哈希表(带有多个域的对象) •支持排序 sets(高得分表,适用于范围查询) •Redis支持事务 •支持将数据设置成过期数据(类似快速缓冲区设计) •Pub/Sub允许用户实现消息机制 最佳应用场景:适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。 例如:股票价格、数据分析、实时数据搜集、实时通讯。 (编注3:Master-slave复制:如果同一时刻只有一台服务器处理所有的复制请求,这被称为 Master-slave复制,通常应用在需要提供高可用性的服务器集群。)&3. MongoDB •所用语言:C++ •特点:保留了SQL一些友好的特性(查询,索引)。 •使用许可: AGPL(发起者: Apache) •协议: Custom, binary( BSON) •Master/slave复制(支持自动错误恢复,使用 sets 复制) •内建分片机制 •支持 javascript表达式查询 •可在服务器端执行任意的 javascript函数 •update-in-place支持比CouchDB更好 •在数据存储时采用内存到文件映射 •对性能的关注超过对功能的要求 •建议最好打开日志功能(参数 –journal) •在32位操作系统上,数据库大小限制在约2.5Gb •空数据库大约占 192Mb •采用 GridFS存储大数据或元数据(不是真正的文件系统) 最佳应用场景:适用于需要动态查询支持;需要使用索引而不是 map/reduce功能;需要对大数据库有性能要求;需要使用 CouchDB但因为数据改变太频繁而占满内存的应用程序。 例如:你本打算采用 MySQL或 PostgreSQL,但因为它们本身自带的预定义栏让你望而却步。 4. Riak&•所用语言:Erlang和C,以及一些Javascript •特点:具备容错能力 •使用许可: Apache •协议: HTTP/REST或者 custom binary •可调节的分发及复制(N, R, W) •用 JavaScript or Erlang在操作前或操作后进行验证和安全支持。 •使用JavaScript或Erlang进行 Map/reduce •连接及连接遍历:可作为图形数据库使用 •索引:输入元数据进行搜索(1.0版本即将支持) •大数据对象支持( Luwak) •提供“开源”和“企业”两个版本 •全文本搜索,索引,通过 Riak搜索服务器查询( beta版) •支持Masterless多站点复制及商业许可的 SNMP监控 最佳应用场景:适用于想使用类似 Cassandra(类似Dynamo)数据库但无法处理 bloat及复杂性的情况。适用于你打算做多站点复制,但又需要对单个站点的扩展性,可用性及出错处理有要求的情况。 例如:销售数据搜集,工厂控制系统;对宕机时间有严格要求;可以作为易于更新的 web服务器使用。&5. Membase •所用语言: Erlang和C •特点:兼容 Memcache,但同时兼具持久化和支持集群 •使用许可: Apache 2.0 •协议:分布式缓存及扩展 •非常快速(200k+/秒),通过键值索引数据 •可持久化存储到硬盘 •所有节点都是唯一的( master-master复制) •在内存中同样支持类似分布式缓存的缓存单元 •写数据时通过去除重复数据来减少 IO •提供非常好的集群管理 web界面 •更新软件时软无需停止数据库服务 •支持连接池和多路复用的连接代理 最佳应用场景:适用于需要低延迟数据访问,高并发支持以及高可用性的应用程序 例如:低延迟数据访问比如以广告为目标的应用,高并发的 web 应用比如网络游戏(例如 Zynga) 6. Neo4j •所用语言: Java •特点:基于关系的图形数据库 •使用许可: GPL,其中一些特性使用 AGPL/商业许可 •协议: HTTP/REST(或嵌入在 Java中) •可独立使用或嵌入到 Java应用程序 •图形的节点和边都可以带有元数据 •很好的自带web管理功能 •使用多种算法支持路径搜索 •使用键值和关系进行索引 •为读操作进行优化 •支持事务(用 Java api) •使用 Gremlin图形遍历语言 •支持 Groovy脚本 •支持在线备份,高级监控及高可靠性支持使用 AGPL/商业许可 最佳应用场景:适用于图形一类数据。这是 Neo4j与其他nosql数据库的最显著区别 例如:社会关系,公共交通网络,地图及网络拓谱 7. Cassandra •所用语言: Java •特点:对大型表格和 Dynamo支持得最好 •使用许可: Apache •协议: Custom, binary (节约型) •可调节的分发及复制(N, R, W) •支持以某个范围的键值通过列查询 •类似大表格的功能:列,某个特性的列集合 •写操作比读操作更快 •基于 Apache分布式平台尽可能地 Map/reduce •我承认对 Cassandra有偏见,一部分是因为它本身的臃肿和复杂性,也因为 Java的问题(配置,出现异常,等等) 最佳应用场景:当使用写操作多过读操作(记录日志)如果每个系统组建都必须用 Java编写(没有人因为选用 Apache的软件被解雇) 例如:银行业,金融业(虽然对于金融交易不是必须的,但这些产业对数据库的要求会比它们更大)写比读更快,所以一个自然的特性就是实时数据分析 8. HBase (配合 ghshephard使用) •所用语言: Java •特点:支持数十亿行X上百万列 •使用许可: Apache •协议:HTTP/REST (支持 Thrift,见编注4) •在 BigTable之后建模 •采用分布式架构 Map/reduce •对实时查询进行优化 •高性能 Thrift网关 •通过在server端扫描及过滤实现对查询操作预判 •支持 XML, Protobuf, 和binary的HTTP •Cascading, hive, and pig source and sink modules •基于 Jruby( JIRB)的shell •对配置改变和较小的升级都会重新回滚 •不会出现单点故障 •堪比MySQL的随机访问性能 最佳应用场景:适用于偏好BigTable:)并且需要对大数据进行随机、实时访问的场合。 例如: Facebook消息数据库(更多通用的用例即将出现)
SGA中的第三个组成部分是共享池。共享池是对sql ,pl/sql 程序进行语法分析、编译、执行的内存区域。共享池包括库缓冲区(library cache)、数据字典缓冲区(Data Directory Cache)用户全局区(User Global Area)。其中库缓冲区含有Sql 语句的分析码、执行计划;数据字典缓冲区含有从数据字典中得到的表、列定义、权限。用户全局区包含用户的MTS 会话信息。
共享池主要用于对SQL 、pl/sql 程序语句进行语法分析、编译、执行、所以,如果应用中药运行大量存储过程或包,则要增加共享池的尺寸。共享池的大小由参数SHARE_POOL_SIZE确定。要了解共享池大小,可以用以下方法:
&……… &Shared_Pool_size&=&&…..&
&SQL&select&name,value&from&v$parameter&where&name&like&‘%size’;&
&SQL&show&parameter&share_pool_size&
共享池应计算存储过程、包等的成功率。
可以查询数据字典 v$rowcache 了解数据字典的成功与失败次数。
&SQL&select&sum(gets)&“dictionary&gets”, &Sum(getmisses)&“dictionary&cache&getmisses” &From&v$rowcache&;&
其中gets 表示读取某一类数据字典的成功次数,getsmisses 表示读取某一类数据字典的失败次数。此外还可以通过查询结果计算共享池中读取数据字典的成功率
&SQL&select&parameter,&get,&getmisses,&getmisses/(getmisses+gets)*100&“miss&ratio”, &(1-&&&&(sum(getmisses)/(sum(getmisses)+sum(gets))&)&)&*100&“hit&ratio” &From&v$rowcache &Where&gets+getmisses0 &Group&by&parameter,gets,&
查询数据字典 v$librarycache 可以计算共享池中库缓存的失败率,结果应该小于1%。
&SQLselect&sum(pins)&“&total&pins”,&sum(reloads)&“&total&reloads”,&sum(reloads)/sum(pins)*100&libarycache&&from&&v$&
其中 total pins 表示驻留内存的次数, total reloads 表示重新加载到内存的次数,librarycache 表示失败率。
上面分析了系统全局区的三个组成部分-----数据缓冲区、日志缓冲区及共享池,如果要得到SGA的总大小,可以在SQL*Plus中使用show sga 命令。
SQL&show sga或查询数据字典
SQL& select * from v$
如果要查询某个参数的大小,可以查询数据字典v_$sagstat,通过计算可以知道sga的使用空间与空闲空间的比。
&SQLcol&OBJECT_NAME&format&a20 &SQL&col&空闲空间百分比(%)&format&90.99 &SQL&select&name, &Sgasize/&&“allocated(M)”&, &Bytes/1024&&&&&&&&“空闲空间(k)”&, &Round(bytes/sagsize*100,2)&&“空闲空间百分比(%)” &From&(&select&sum(bytes)&sgasize&from&sys.v_$sgastat)&s&,sys.v_$sgastat&f &Where&f.name=’free&memory’&;&&
关于Oracle 10g内存结构之共享池的相关知识及使用方法就介绍到这里了,希望本次的介绍能够对您有所收获!
我们知道,内存结构是Oracle体系结构中最重要的部分之一。按照系统对内存使用方法的不同,可以分为系统全局区(SGA)、程序全局区(PGA)、排序区(Sort Area)、大池(Large Pool)、及java池(java Pool),本文我们先介绍一下Oracle 10g内存结构之系统全局区的内容,接下来我们就开始介绍这部分内容。
系统全局区(System Global Area)
它是一组为系统分配的内存共享结构,可以包含一个数据库实例的数据和控制信息。如果多个用户连接到一个实例,在实例的系统全局区中,数据可以被多个用户共享,所以又称共享全局区。系统全局区按其作用不同,可以分为数据缓冲区、日志缓冲区及共享池。
数据缓冲区:
数据缓冲区用于从磁盘读入的数据,供所有用户共享。
修改的数据、插入的数据存储在数据缓冲区中,修改完成或DBWR进程的其他条件引发时,数据被写入数据文件
数据缓冲区工作原理:
LRU (Least recently used):最近最少使用原则的缩写,是一种数据缓冲区的一种管理机制,,只保留最近数据,不保留旧数据。
Dirty:表示脏数据,脏数据是修改后还没有写到数据文件的数据。
Oracle10g 的数据库内存的设置参数不再由DB_BLOCK_BUFFERS确定,而是由oracle的新参数DB_CACHE_SIZE 和DB_nK_CACHE_SIZE确定,不同的数据段可以使用不同的数据块。大表可以存储在大的数据块表空间中,小表可以存储在小的数据块表空间中,以优化i/o性能。对于系统表空间、临时表空间、及其它默认设置的表空间,可以使用标准的数据块DB_BLOCK_SIZE确定。
标准数据块DB_BLOCK_SIZE用于系统表空间及默认表空间,其他表空间可以使用非标准数据块BLOCKSIZE(创建表空间时使用),其值分别为 2k 4k 8k 16k 32k ,非标准数据块的数据缓冲区使用参数DB_Nk_CACHE_SIZE确定。
需要注意的是BLOCKSIZE不得用于标准块。如果设置了DB_BLOCK_SIZE=2048,则不得设置DB_2K_CACHE_SIZE,标准块必须使用参数DB_CACHE_SIZE 来设置。同时可以在线修改数据缓冲区参数:SQL& alter system set db_2k_cache_size = 10M ;如果要查询数据缓冲区大小,可以如下:SQL& show parameter db。
在创建不同数据块表空间时,要使用参数BLOCKSIZE指出数据块的大小,同时在参数文件中要使用DB_Nk_CACHE_SIZE 进行配置,与BLOCKSIZE的个数相对应,否则会出现错误。
设置动态内存时,可以将多个参数全部写入参数文件,格式如下:#&cache&and&i/o &&DB_BLOCK_SIZE=4096&&DB_CACHE_SIZE=&&DB_2K_CACHE_SIZE=8M&&DB_8K_CACHE_SIZE=4M&&……..&
其中,参数 DB_CACHE_SIZE 只适用于系统表空间、临时表空间、及默认表空间,DB_2K_CACHE_SIZE& 适合 BLOCKSIZE 为2K的表空间。8K 也是一样的道理。
数据缓冲区对数据库德存取速度又直接影响。一般的缓冲区命中率应该在90% 以上。例如,使用数据字典 v$sysstat 计算数据缓冲区命中率:SQL&select&a.value+b.value&“logical_reads”&,&c.value&“phys_reads”, &&&&&&&Round(100*&(&(&a.value+b.value)-&c.value)&/ &&&&&&&(&a.value+b.value&)&)&“buffer&hit&radio&“ &&&&&&&From&v$sysstat&a,&v$sysstat&b,v$sysstat&c &&&&&&&Where&a.statistic#=38&and&b.statistic#=39&and&c.statistic#=40;&
下面是计算数据缓冲命中率的另一种方法:SQL&select&name,&value &&&&&&&From&v$sysstat &&&&&&&Where&name&in&(&‘session&logical&reads’,’physical&reads’,physical&reads&direct’,&‘physical&reads&direct&(lob)’);&
其中:Session logical reads 为读的总量。Physical reads为从数据文件读。Physical reads direct 为从缓冲区读(不含lobs)。Physical reads direct (lobs) 为从缓冲区读(含lobs)。Hit Ratio = 1- ( ( physical reads- physical reads direct – physical reads direct(lob) ) /session logical reads) = 95%。
日志缓冲区
日志缓冲区用来存储数据库的修改信息。日志信息首先在日志缓冲区中产生,当日志缓冲区的日志达到一定数量时,由日志写入进程LGWR将日志数据写入日志文件组,再经过切换,由归档进程ARCH将日志数据写入归档介质。
日志缓冲区大小由参数LOG_BUFFER确定,要查询日志缓冲区大小可以用以下方法:
方法一:参数文件中:&…… &&Processes&=&150&&Parallel_max_servers&=&5&Log_buffer&=&32768&……..&
方法二:SQL&select&name,value&from&v$parameter&where&name&like&‘%buffer’;&
方法三:SQL&show&parameter&log_buffer&
对于日志缓冲区而言可以计算失败率,使用数据字典v$latch 计算日志缓冲区的失败率SQLselect&name,gets,misses,immediate_gets,immediate_misses, &&&&&&Decode(gets,0,0,misses/gets*100)&ratiol, &&&&&&Decode&(immediate_gets+immediate_misses,0,0, &immediate_misses/(immediate_gets+immediate_misses)*100)&&&ratio2 &&&&&&from&v$latch &&&&&&where&name&in&(‘redo&allocation’,&‘redo&copy’);&
Gets 表示成功等待日志缓冲区的次数。
Immediate gets 表示成功立即得到日志缓冲区的次数。
Immediate misses 表示未成功立即得到日志缓冲区的次数。
等待表示日志在进入日志缓冲区时,因为日志缓冲区过小而没有空闲空间,所以日志缓冲区的失败可以表示日志缓冲区是否足够大,不够大时,用户的日志写将产生等待过程。日志缓冲区的失败率应该小于1%。
此外,可以查询用户进程等待日志缓冲区时的次数,通过数据字典v$sysstat 得到:SQL&select&name,value&from&v$sysstat &&&&&&&Where&name&=&‘&redo&buffer&allocation&retries’&;&
关于Oracle 10g内存结构之系统全局区的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!
本文是关于Oracle数据库调试与优化方面的文章,主要介绍Oracle数据库中命中率相关的问题,包括不同的算法之间性能的比对。关于Oracle中各个命中率的计算以及相关的调优 1) Library Cache的命中率: 计算公式:Library Cache Hit Ratio = sum(pinhits) / sum(pi
本文是关于Oracle数据库调试与优化方面的文章,主要介绍Oracle数据库中命中率相关的问题,包括不同的算法之间性能的比对。关于Oracle中各个命中率的计算以及相关的调优
1)Library Cache的命中率:计算公式:Library Cache Hit Ratio = sum(pinhits) / sum(pins)
SELECT SUM(pinhits)/sum(pins) FROM V$LIBRARYCACHE;
通常在98%以上,否则,需要要考虑加大共享池,绑定变量,修改cursor_sharing等参数。
2)计算共享池内存使用率:
SELECT (1 - ROUND(BYTES / (&TSP_IN_M * 1024 * 1024), 2)) * 100 || '%'
FROM V$SGASTAT WHERE NAME = 'free memory' AND POOL = 'shared pool';
其中: &TSP_IN_M是你的总的共享池的SIZE(M)
共享池内存使用率,应该稳定在75%-90%间,太小浪费内存,太大则内存不足。
查询空闲的共享池内存:
SELECT * FROM V$SGASTAT WHERE
NAME = 'free memory' AND POOL = 'shared pool';
3)db buffer cache命中率:计算公式:Hit ratio = 1 - [physical reads/(block gets + consistent gets)]
SELECT NAME, PHYSICAL_READS, DB_BLOCK_GETS, CONSISTENT_GETS,
1 - (PHYSICAL_READS / (DB_BLOCK_GETS + CONSISTENT_GETS))&
"Hit Ratio" FROM V$BUFFER_POOL_STATISTICS WHERE NAME='DEFAULT';
通常应在90%以上,否则,需要调整,加大DB_CACHE_SIZE
外一种计算命中率的方法(摘自ORACLE官方文档&&数据库性能优化&&):
命中率的计算公式为:
Hit Ratio = 1 - ((physical reads - physical reads direct - physical reads direct (lob)) / (db block gets + consistent gets - physical reads direct - physical reads direct (lob))
分别代入上一查询中的结果值,就得出了Buffer cache的命中率
SELECT NAME, VALUE FROM V$SYSSTAT WHERE NAME IN(
'session logical reads', 'physical reads',&
'physical reads direct', 'physical reads direct (lob)',&
'db block gets', 'consistent gets');
4)数据缓冲区命中率:
SQL& select value from v$sysstat where name ='physical reads';&
SQL& select value from v$sysstat where name ='physical reads direct';&
SQL& select value from v$sysstat where name ='physical reads direct (lob)';&
SQL& select value from v$sysstat where name ='consistent gets';&
SQL& select value from v$sysstat where name = 'db block gets';
这里命中率的计算应该是令 x = physical reads direct + physical reads direct (lob),命中率 =100 - ( physical reads - x) / (consistent gets + db block gets - x)*100,通常如果发现命中率低于90%,则应该调整应用可可以考虑是否增大数据缓冲区
5)共享池的命中率:
select sum(pinhits-reloads)/sum(pins)*100 "hit radio"
假如共享池的命中率低于95%,就要考虑调整应用(通常是没使用bind var )或者增加内存
6)计算在内存中排序的比率:
SELECT * FROM v$sysstat t WHERE NAME='sorts (memory)';
查询内存排序数&
SELECT * FROM v$sysstat t WHERE NAME='sorts (disk)';
查询磁盘排序数caculate sort in memory ratio&
SELECT round(&sort_in_memory/(&sort_in_memory+&sort_in_disk),4)*100||'%' FROM
此比率越大越好,太小整要考虑调整,加大PGA
7)PGA的命中率:
计算公式:BP x 100 / (BP + EBP)
BP: bytes processed
EBP: extra bytes read/written
SELECT * FROM V$PGASTAT WHERE NAME='cache hit percentage';
或者从OEM的图形界面中查看
我们可以查看一个视图以获取Oracle的建议值:
SELECT round(PGA_TARGET_FOR_ESTIMATE/) target_mb,
ESTD_PGA_CACHE_HIT_PERCENTAGE cache_hit_perc, ESTD_OVERALLOC_COUNT&
FROM V$PGA_TARGET_ADVICE;&
The output of this query might look like the following:&
TARGET_MB CACHE_HIT_PERC ESTD_OVERALLOC_COUNT
63 23 367&
125 24 30&
在此例中:PGA至少要分配375M
我个人认为PGA命中率不应该低于50%
以下的SQL统计sql语句执行在三种模式的次数: optimal memory size, one-pass memory size, multi-pass memory size:
SELECT name profile, cnt, decode(total, 0, 0, round(cnt*100/total,4))&
percentage FROM (SELECT name, value cnt, (sum(value) over ())&
total FROM V$SYSSTAT WHERE name like 'workarea exec%');
8)共享区字典缓存区命中率
计算公式:SUM(gets - getmisses - usage -fixed) / SUM(gets)
命中率应大于0.85
select sum(gets-getmisses-usage-fixed)/sum(gets) from v$
9)数据高速缓存区命中率
计算公式:1-(physical reads / (db block gets + consistent gets))
命中率应大于0.90最好
select name,value from v$sysstat where name in ('physical reads','db block gets','consistent gets');
10)共享区库缓存区命中率
计算公式:SUM(pins - reloads) / SUM(pins)
命中率应大于0.99
select sum(pins-reloads)/sum(pins) from v$
11)检测回滚段的争用
SUM(waits)值应小于SUM(gets)值的1%
select sum(gets),sum(waits),sum(waits)/sum(gets) from v$
12)检测回滚段收缩次数
select name,shrinks from v$rollstat, v$rollname&
where v$rollstat.usn = v$rollname.
几个常用的检查语句
1. 查找排序最多的SQL:
SELECT HASH_VALUE, SQL_TEXT, SORTS, EXECUTIONS&
FROM V$SQLAREA ORDER BY SORTS DESC;
2.查找磁盘读写最多的SQL:
SELECT * FROM (SELECT sql_text,disk_reads "total disk" ,&
executions "total exec",disk_reads/executions "disk/exec"
FROM v$sql WHERE executions&0 and is_obsolete='N' ORDER BY
4 desc) WHERE ROWNUM&11 ;
3.查找工作量最大的SQL(实际上也是按磁盘读写来排序的):
select substr(to_char(s.pct, '99.00'), 2) || '%' load,
s.executions executes,p.sql_text from(select address,disk_reads,executions,pct,rank() over&
(order by disk_reads desc) ranking from (select
address,disk_reads,executions,100 * ratio_to_report
(disk_reads) over () pct from sys.v_$sql where
command_type != 47) where disk_reads & 50 * executions) s,
ys.v_$sqltext p where s.ranking &= 5 and p.address = s.address&
order by 1, s.address, p.
4. 用下列SQL工具找出低效SQL:
select executions,disk_reads,buffer_gets,round((buffer_gets-
disk_reads)/buffer_gets,2) Hit_radio,round(disk_reads/executions,2)
reads_per_run,sql_text From v$sqlarea Where executions&0 and
buffer_gets &0 and (buffer_gets-disk_reads)/buffer_gets&0.8&
Order by 4 desc;
5、根据sid查看对应连接正在运行的sql
select /*+ push_subq */command_type,sql_text,sharable_mem,persistent_mem,
runtime_mem,sorts,version_count,loaded_versions,open_versions,
users_opening,executions,users_executing,loads,first_load_time,
invalidations,parse_calls,disk_reads,buffer_gets,rows_processed,
sysdate start_time,sysdate finish_time,’&’||address&
sql_address,’N’status From v$sqlarea Where address=
(select sql_address from v$session where sid=&sid);
***************Oracle 缓冲区命中率低的分析及解决办法******************
首先确定下面的查询结果:
1,缓冲区命中率的查询(是否低于90%):
select round((1 - sum(decode(name,'physical reads',value,0)) /&
(sum(decode(name,'db block gets',value,0)) + sum(decode(name,'
consistent gets',value,0))) ),4) *100 || '%' chitrati from v$
2,使用率的查询(有无free状态的数据快.):
select count(*), status from v$bh group by
3,相关等待事件的查询(是否有相关等待事件)
select event,total_waits from v$system_event where event&
in ('free buffer waits');
4,当前大小(是否已经很大)
select value/ cache_size from v$parameter&
where name='db_cache_size'
5,top等待事件分析(Db file scatered read的比率是否大)
select event ,total_waits,suml from (select
event,total_waits,round(total_waits/sumt*100,2)||'%' suml&
from (select event,total_waits from v$system_event ),&
(select sum(total_waits) sumt from v$system_event)&
order by total_waits desc) where rownum&6 and event&
not like 'rdbms%' and event not like 'pmon%' and event&
not like 'SQL*Net%' and event not like 'smon%';
6,db_cache_advice建议值(9i后的新特性,可以根据他更好的调整cache_size)
select block_size,size_for_estimate,size_factor,
estd_physical_reads from v$db_cache_
缓冲区命中率(低于90的命中率就算比较低的).
没有free不一定说明需要增加,还要结合当前cache_size的大小(我们是否还可以再增大,是否有需要增加硬件,增加开销),
空闲缓冲区等待说明进程找不到空闲缓冲区,并通过写出灰缓冲区,来加速数据库写入器生成空闲缓冲区,当DBWn将块写入磁盘后,灰数据缓冲区将被释放,以便重新使用.产生这种原因主要是:
1,DBWn可能跟不上写入灰缓冲区:i/0系统较慢,尽量将文件均匀的分布于所有设备,
2,缓冲区过小或过大。
3,可以增加db_writer_processes数量。
4,可能有很大的一个事物,或者连续的大事物
我们需要长期观察这个事件是否长期存在并数值一直在增大,如果一直在增大,则说明需要增大db_cache大小.或优化sql.
数据分散读等待,通常表现存在着与全表扫描相关的等待,逻辑读时,在内存中进行的全表扫描一般是零散地,而并非连续的被分散到缓冲区的各个部分,可能有索引丢失,或被仰制索引的存在。该等待时间在数据库会话等待多块io读取结束的时候产生,并把指定的块数离散的分布在数据缓冲区。这意味这全表扫描过多,或者io不足或争用,
存在这个事件,多数都是问题的,这说明大量的全部扫描而未采用索引.
db_cache_advice对我们调整db_cache_size大小有一定的帮助,但这只是一个参考,不一定很精确。
通过上面6种情况的综合分析,判断是否需要增加大cache_size. 或者把常用的(小)表放到keep区。
但多数的时候做这些不会解决质的问题,
而真正的问题主要是对sql语句的优化(如:是否存在大量的全表扫描等)
索引是在不需要改变程序的情况下,对数据库性能,sql语句提高的最实用的方法.
我在生产中遇到过类似的问题,200M的cache_size,命中率很低21%,但通过对sql语句的优化(添加索引,避免全表扫描),命中率增加到96%,程序运行时间由原来的2小时减少到不到10分钟.
这就提到了怎么定位高消耗的sql问题.全表扫描的问题,在这里不做细致的解说,这里只说明方法,我会在相关的章节专门介绍怎么使用这些工具
1,sql_trace跟踪session.用tkprof 分别输出磁盘读,逻辑读,运行时间长的sql进行优化.这些高消耗的sql一般都伴随着全表扫描.
2,statspack分析.在系统繁忙时期进行时间点的统计分析,产看TOP事件是否有Db file scatered read.并查看TOP sql语句是否存在问题等.
还要说一句:当然在硬件允许的情况下,尽量增大db_cache_size 减少磁盘读,但并不是越大越好,一定要根据自己的库数据量的程度来调节,因为大的db_cache_size同样会增大数据库管理的开销,当然可能开销并不会明显的影响数据库的性能,硬件价格也越来越低,这就需要我们具体问题具体分析了,在我看来物尽其用就最好了,尽量不要浪费,找到问题的本质。调优是一件很艺术的事。
***********************Oracle数据库缓冲区命中率*****************
1、查看Oracle数据库缓冲区命中率
select a.value + b.value "logical_reads", c.value "phys_reads",&
round(100 * ((a.value+b.value)-c.value) / (a.value+b.value))&
"BUFFER HIT RATIO" from v$sysstat a, v$sysstat b, v$sysstat c&
where a.statistic# = 40 and b.statistic# = 41 and c.statistic# = 42;
2、Tags: oracle
数据库缓冲区命中率:
select value from v$sysstat where name ='physical reads';&
value 3714179&
select value from v$sysstat where name ='physical reads direct';&
select value from v$sysstat where name ='physical reads direct(lob)';
select value from v$sysstat where name ='consistent gets';&
select value from v$sysstat where name ='db block gets';&
这里命中率的计算应该是
令x=physical reads direct + physical reads direct(lob)
命中率=100-(physical reads -x)/(consistent gets +db block gets -x)*100
通常如果发现命中率低于90%,则应该调整应用可以考虑是否增大数据加
共享池的命中率
select sum(pinhits)/sum(pins)*100 "hit radio" from v$
如果共享池的命中率低于95%就要考虑调整应用(通常是没应用bind var)或者增加内存。
关于排序部分
select name,value from v$sysstat where name like '%sort%';
如果我们发现sorts(disk)/(sorts(memory)+sorts(disk))的比例过高,则通常意味着sort_area_size部分内存教较小,可考虑调整相应的参数。
关于log_buffer
select name,value from v$sysstat where name
in ('redo entries','redo buffer allocation retries');
假如redo buffer allocation retries/redo entries的比例超过1%我们就可以考虑增加log_buffer.
1.统计信息简介 统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。比如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于统计信息。CBO正是根据这些统计信息数据,计算出不同访问路
1.统计信息简介
统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。比如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于统计信息。CBO正是根据这些统计信息数据,计算出不同访问路径下,不同join&方式下,各种计划的成本,最后选择出成本最小的计划。
在CBO(基于代价的优化器模式)条件下,SQL语句的执行计划由统计信息来决定,若没有统计信息则会采取动态采样的方式决定执行计划!可以说统计信息关乎sql的执行计划是否正确,属于sql执行的指导思想,oracle的初始化参数statistics_level控制收集统计信息的级别,有三个参数值:
BASIC :收集基本的统计信息
TYPICAL:收集大部分统计信息(数据库的默认设置)
ALL:收集全部统计信息
Oracle 10g之后,Query Optimizer就已经将CBO作为默认优化器,并且Oracle官方不再支持RBO服务。但是,通过优化器参数optimizer_mode,我们可以控制Oracle优化器生成不同模式下的执行计划。
关于优化器的请参考:《》
2.如何收集统计信息
2.1&统计信息的内容:
1)Table statistics
Number of rows --行数量
Number of blocks --block数量
Average row length --平均行的长度.
2)Column statistics
Number of distinct values (NDV) in column --列中distinct的值
Number of nulls in column --列中null的值
Data distribution (histogram)& --数据分布
3)Index statistics
Number of leaf blocks --子节点的块数量
Levels --子节点数量
Clustering factor --集群因子
4)System statistics
I/O performance and utilization --IO性能和利用率
CPU performance and utilization --CPU的性能和利用率
2.2&收集统计信息
Oracle Statistic&的收集,可以使用analyze&命令,也可以使用DBMS_STATS&包来收集,Oracle&建议使用DBMS_STATS包来收集统计信息,因为DBMS_STATS包收集的更广,并且更准确。analyze&在以后的版本中可能会被移除。
DBMS_STATS常用的几个过程如下:
dbms_stats.gather_table_stats 收集表、列和索引的统计信息;
dbms_stats.gather_schema_stats 收集SCHEMA下所有对象的统计信息;
dbms_stats.gather_index_stats 收集索引的统计信息;
dbms_stats.gather_system_stats 收集系统统计信息
dbms_stats.GATHER_DICTIONARY_STATS:所有字典对象的统计;
DBMS_STATS.GATHER_DICTIONARY_STATS 其收集所有系统模式的统计
dbms_stats.delete_table_stats 删除表的统计信息
dbms_stats.delete_index_stats 删除索引的统计信息
dbms_stats.export_table_stats 输出表的统计信息
dbms_stats.create_state_table
dbms_stats.set_table_stats 设置表的统计
dbms_stats.auto_sample_size
analyze&命令的语法如下:
SQL&analyze table tablename compute statistics;
SQL&analyze table tablename compute statistics for all
SQL&analyze table tablename delete statistics
2.3&统计信息的分类
Oracle&的Statistic 信息的收集分两种:自动收集和手工收集。
Oracle&的Automatic Statistics Gathering&是通过Scheduler&来实现收集和维护的。Job&名称是GATHER_STATS_JOB,&该Job收集数据库所有对象的2种统计信息:
(1)Missing statistics(统计信息缺失)
(2)Stale statistics(统计信息陈旧)
该Job&是在数据库创建的时候自动创建,并由Scheduler来管理。Scheduler 在maintenance windows open时运行gather job。&默认情况下,job&会在每天晚上10到早上6点和周末全天开启。该过程首先检测统计信息缺失和陈旧的对象。然后确定优先级,再开始进行统计信息。
Scheduler Job的stop_on_window_close&属性控制GATHER_STATS_JOB&是否继续。该属性默认值为True.&如果该值设置为False,那么GATHER_STATS_JOB 会中断,&而没有收集完的对象将在下次启动时继续收集。
Gather_stats_job&调用dbms_stats.gather_database_stats_job_proc过程来收集statistics 的信息。&该过程收集对象statistics的条件如下:
(1)对象的统计信息之前没有收集过。
(2)当对象有超过10%的rows&被修改,此时对象的统计信息也称为stale statistics。
但是对于高度变化的表在白天的活动期间被TRUNCATE/DROP并重建或者块加载超过本身总大小10%的对象;我们可以将这些表上的统计设置为NULL
可以通过以下SQL来查看:
select job_name, program_name, enabled, stop_on_window_close
&&from dba_scheduler_jobs
&where job_name = 'gather_stats_job';
为了决定是否对对象进行监控,Oracle 提供了一个参数STATISTICS_LEVEL。通过设置初始化参数STATISTIC_LEVEL&为TYPICAL&或ALL,就可以自动收集统计信息(默认值为TYPICAL,因此可以随即启用自动收集统计信息的功能)。STATISTIC_LEVEL&参数的值可以激活GATHER_STATS_JOB。
在10g中表监控默认是激活的,如果STATISTICS_LEVEL设置为basic,不仅不能监控表,而且将禁掉如下一些10g的新功能:
(1)ASH(Active Session History)
(2)ASSM(Automatic Shared Memory Management)
(3)AWR(Automatic Workload Repository)
(4)ADDM(Automatic Database Diagnostic Monitor)
sys@ORCL& show parameter statistics_
NAME&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& TYPE&&&&&&& VALUE
statistics_level&&&&&&&&&&&&&&&&&&&& string&&&&& TYPICAL
当启动对象的监控后,从上次统计信息收集之后的的信息,如inserts,updates,deletes 等,这些改变的信息会记录到user_tab_modifications&视图。
当对象的数据发生改变之后,&经过几分钟的延时,这些信息写入到user_tab_modifications视图,然后dbms_stats.flush_database_monitoring_info过程就会发现这些信息,并讲这些信息保存在内存中。
当监控的对象被修改的部分超过10%时,gather_database_stats&或者gather_schema_stats&过程就会去收集这些stale statistics
3.统计信息的存储位置以及常用数据字典
3.1&统计信息常用数据字典
统计信息收集如下数据:
(1)表自身的分析:&包括表中的行数,数据块数,行长等信息。
(2)列的分析:包括列值的重复数,列上的空值,数据在列上的分布情况。
(3)索引的分析:&包括索引叶块的数量,索引的深度,索引的聚合因子等。
这些统计信息存放在以下的数据字典里:
DBA_TABLES
DBA_OBJECT_TABLES
DBA_TAB_STATISTICS
DBA_TAB_COL_STATISTICS
DBA_TAB_HISTOGRAMS
DBA_INDEXES
DBA_IND_STATISTICS
DBA_CLUSTERS
DBA_TAB_PARTITIONS
DBA_TAB_SUBPARTITIONS
DBA_IND_PARTITIONS
DBA_IND_SUBPARTITIONS
DBA_PART_COL_STATISTICS
DBA_PART_HISTOGRAMS
DBA_SUBPART_COL_STATISTICS
DBA_SUBPART_HISTOGRAMS
3.2&表的统计信息
包含表行数,使用的块数,空的块数,块的使用率,行迁移和链接的数量,pctfree,pctused的数据,行的平均大小:
SELECT NUM_ROWS,
EMPTY_BLOCKS,
AVG_SPACE,
CHAIN_CNT,
AVG_ROW_LEN
FROM USER_TABLES
3.3索引列的统计信息
包含索引的深度(B-Tree的级别),索引叶级的块数量,集群因子(clustering_factor),&唯一值的个数。
SELECT BLEVEL,
LEAF_BLOCKS,
DISTINCT_KEYS,
AVG_LEAF_BLOCKS_PER_KEY,
AVG_DATA_BLOCKS_PER_KEY,
CLUSTERING_FACTOR
FROM USER_INDEXES
3.4 列的统计信息
包含唯一的值个数,列最大小值,密度(选择率),数据分布(直方图信息),NUll值个数
SELECT NUM_DISTINCT,
LOW_VALUE,
HIGH_VALUE,
NUM_NULLS,
NUM_BUCKETS,
FROM USER_TAB_COLUMNS
对于统计信息的搜集,谈谈个人的几点理解:
1.统计信息默认是存放在数据字典表中的,也只有数据字典中的统计信息,才会影响到CBO。
2.DBMS_STATS 提供的CREATE_STAT_TABLE 过程,只是生成一个用户自定义的特定格式的表,用来存放统计信息罢了,这个表中的统计信息是不会影响到统计信息的。
3.GATHER 系列过程中,如果指定stattab,statid,statown 参数(也可以不指定),则是搜集的统计信息除了更新到数据字典外,还在statown 用户下的stattab 表中存放一份,标示为
4.EXPORT和IMPORT 系列的过程中,stattab,statid,statown 参数不能为空,分别表示把数据字典中的当前统计信息导出到用户自定义的表中,以及把用户表中的统计信息导入到数据字典中,很明显可以看出,这里的导入操作和上面GATHER 操作会改变统计信息,可能会引起执行执行计划的改变,因此要慎重操作。
5.每次统计信息搜集前,将旧的统计信息备份起来是很有必要的;特别是保留一份或多份系统在稳定时期的统计信息也是很有必要的。
6.多长时间搜集一次统计信息,对于统计信息如何备份和保留,搜集统计信息时如何选择合适的采样,并行,直方图设置等都比较重要,需要设计一个较好的统计信息搜集策略。
在OCP 10g考试中会有个跟统计信息相关的考试题:
1. In your Oracle 10g database , you have scheduled a job to update the optimizer statistics at 05:00 pm
every Friday. The job has successfully completed. Which three pieces of information would you check to
confirm that the statistics have been collected? (Choose three.)
A. average row size
B. last analyzed date
C. size of table in bytes
D. size of table in database blocks
E. number of free blocks in the free list
F. number of extents present in the table
Answer: ABD
&&&& 摘要: 以下测试环境为Oracle 10g 10.2.0.4版本,测试对Oracle的统计信息的收集与管理。首先依据dba_objects创建一张测试表:
SQL& create table eygle as select * from dba_&Table created对该表进行统计信息收集,这里未指定method_opt,则Oracle将采用 FOR ALL COL...&&
&&&& 摘要: 获取昨天:
select trunc(SYSDATE-1) &
检查一下:
select to_char (trunc(SYSDATE-1),'yyyy-mm-dd HH24:MI:SS')
获取上个月第一天00:00:00:
&select add_months(trunc(sysdate,'MON'),-1) from d...&&
Oracle数据库启动分为三个步骤:
nomount,找到初始化文件pfile或者spfile,创建SGA并启动后台进程但不允许访问数据库。
mount,根据初始化文件找到控制文件(Control File),为某些DBA活动装载数据库但不允许用户访问数据库。
open,根据控制文件找到数据文件(Data File),重做日志文件(Redo File),使用户可以访问数据库。
关闭数据库的4个不同命令
shutdown normal(等于shutdown)
正常是关闭的缺省方式正常的数据库关闭在下列情况下进行
• 不允许新的连接
• 等待会话结束
• 等待事务结束
• 做一个检查点并关闭数据文件
• 下一次启动时将不要求实例恢复
shutdown transactional
事务处理关闭防止客户丢失工作事务处理数据库关闭在下列情况下进行
• 不允许新的连接
• 不等待会话结束
• 等待事务结束
• 做一个检查点并关闭数据文件
• 下一次启动将不要求实例恢复
shutdown immediate
立即关闭数据库在下列情况下进行
• 不允许新的连接
• 不等待会话结束
• 不等待事务结束
• 未结束的事务自动回滚(rollback)
• 做一个检查点并关闭数据文件
• 下一次启动将不要求例程恢复
shutdown abort
如果正常和立即关闭选项不起作用可以中止当前数据库例程中止例程可以在下列情况下进行
• 不允许新的连接
• 不等待会话结束
• 不等待事务结束
• 不做检查点且没有关闭数据文件
• 下一次启动将要求实例恢复
启动数据库相关命令
startup(默认启动到open状态)
startup nomount
startup mount
初始化文件
pfile,文本文件,可以手工编辑该文件
spfile,二进制文件,不能手工修改里面的参数,只能使用数据库命令进行修改,数据库启动默认使用spfile
查看初始化文件路径
根据spfile创建pfile文件
create pfile='/u01/app/pfile.ora'
create spfile from pfile='/u01/app/pfile.ora';
查看控制文件的路径
select name from v$
查看控制文件的内容,可以根据ctl.trc重建控制文件
alter database backup controlfile to trace as '/u01/app/ctl.trc';
查看数据文件的位置
select name from v$
查看重做日志文件的位置
select member from v$
数据库的密码文件
Windows,$ORACLE_HOME/database/PWDorcl.ora
Linux/Unix,$ORACLE_HOME/dbs/orapworcl
密码文件的作用是允许数据库的sysdba、sysoper用户通过口令来远登陆
查看数据库是否允许用户远程登陆数据库
show parameter remote_login_
如果remote_login_passwordfile为EXCLUSIVE则表示允许远程连接数据库
如果remote_login_passwordfile为NONE则表示不允许远程连接数据库
禁止用户远程登陆数据库(需要重启数据库生效)
alter system set remote_login_passwordfile=none scope=
select * from dba_
select * from dba_data_
重做日志文件
select * from v$
重做日志文件的状态
STALE表示数据已经提交到数据库中,空白状态表示正在使用该文件
1.& && &如何查看及解决最耗CPU的SQL语句1.1.&&用top监控服务器负载
[root@node1 ~]# top
top - 22:51:02 up 56 min,&&1 user,&&load average: 0.00, 0.00, 0.00
Tasks:&&96 total,& &1 running,&&95 sleeping,& &0 stopped,& &0 zombie
Cpu(s):&&0.0%us,&&0.0%sy,&&0.0%ni,100.0%id,&&0.0%wa,&&0.0%hi,&&0.0%si,&&0.0%st
Mem:& &1035096k total,& &351488k used,& &683608k free,& & 24140k buffers
Swap:&&2096472k total,& && &&&0k used,&&2096472k free,& &270360k cached
&&PID USER& && &PR&&NI&&VIRT&&RES&&SHR S %CPU %MEM& & TIME+&&COMMAND& && && && && &
& & 1 root& && &15& &0&&&&560 S&&0.0&&0.1& &0:00.22 init& && && && && && &&&
& & 2 root& && &RT&&-5& &&&0& & 0& & 0 S&&0.0&&0.0& &0:00.00 migration/0& &
& && && &如果发现user中的CPU过高,比如oracle中最高的进程pid为1138782,占CPU27%,则执行下一步。1.2.&&查询数据库会话的sid、serial#
进入数据库,根据oracle进程的pid查出对应数据库会话的sid、serial#:
select s.sid,s.serial#
from v$session s,v$process p
where s.paddr=p.addr and p.spid='1138782';
& && && &查询出来的结果sid、serial#分别为482、567671.3.&&查询SQL语句
根据数据库会话的sid查出具体的SQL语句:
desc v$sqltext
名称& && && && && && && && && && && && &&&是否为空? 类型
----------------------------------------- -------- --------------
ADDRESS& && && && && && && && && && && && && && &&&RAW(4)
HASH_VALUE& && && && && && && && && && && && && &&&NUMBER
COMMAND_TYPE& && && && && && && && && && && && &&&NUMBER
PIECE& && && && && && && && && && && && && && && &&&NUMBER
SQL_TEXT& && && && && && && && && && && && && && & VARCHAR2(64)
select sql_text
from v$sqltext a
where a.hash_value=(select sql_hash_value from v$session b
& && && && && && & where b.sid='&sid')
输入 sid 的值:1.4.&&处理SQL语句
如果SQL语句影响了数据库的运行,可以kill掉SQL语句的会话:
①在数据库中杀死SQL语句的会话:
alter system kill session '482,56767';
& && && &如果不能在数据库中杀死SQL语句,可在LINUX系统中强制杀死Oracle进程
& && && &②在linux系统中强制杀死oracle进程
#kill -9 1138782
1.5.&&SQL语句优化
最后可以根据步骤(3)查询出来的SQL语句进行优化,以避免再次出现上述消耗CPU的情况。
&&&& 摘要: 一. 分区表理论知识
Oracle提供了分区技术以支持VLDB(Very Large DataBase)。分区表通过对分区列的判断,把分区列不同的记录,放到不同的分区中。分区完全对应用透明。
Oracle的分区表可以包括多个分区,每个分区都是一个独立的段(SEGMENT),可以存放到不同的表空间中。查询时可以通过查询表来访问各个分区中的数据,也可以通过在查询时直接指定分区的方法来进行查询。 ...&&
1.分区表的维护注意事项
若分区表跨不同表空间,做导出、导入时目标数据库必须预建这些表空间。分表区各区所在表空间在做导入时目标数据库一定要预建这些表空间!这些表空间不一定是用户的默认表空间,只要存在即可。如果有一个不存在,就会报错!默认时,对分区表的许多表维护操作会使全局索引不可用,标记成UNUSABLE。 那么就必须重建整个全局索引或其全部分区。如果已被分区,Oracle 允许在用于维护操作的ALTER TABLE 语句中指定UPDATE GLOBAL INDEXES 来重载这个默认特性,指定这个子句也就告诉Oracle 当它执行维护操作的DDL 语句时更新全局索引,这提供了如下好处:
在操作基础表的同时更新全局索引这就不需要后来单独地重建全局索引;因为没有被标记成UNUSABLE, 所以全局索引的可用性更高了,甚至正在执行分区的DDL 语句时仍然可用索引来访问表中的其他分区,避免了查询所有失效的全局索引的名字以便重建它们;
另外在指定UPDATE GLOBAL INDEXES 之前还要考虑如下性能因素:
因为要更新事先被标记成UNUSABLE 的索引,所以分区的DDL 语句要执行更长时间,当然这要与先不更新索引而执行DDL 然后再重建索引所花的时间做个比较,一个适用的规则是如果分区的大小小于表的大小的5% ,则更新索引更快一点;DROP TRUNCATE 和EXCHANGE 操作也不那么快了,同样这必须与先执行DDL 然后再重建所有全局索引所花的时间做个比较;要登记对索引的更新并产生重做记录和撤消记录,重建整个索引时可选择NOLOGGING;重建整个索引产生一个更有效的索引,因为这更利于使用空间,再者重建索引时允许修改存储选项;分区索引结构表不支持UPDATE GLOBAL INDEXES 子句。 2.普通表变为分区表
将已存在数据的普通表转变为分区表,没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,一般可以有三种方法,视不同场景使用:2.1方法一:利用原表重建分区表。
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO t
SELECT Rownum, SYSDATE - Rownum FROM Dba_Objects WHERE Rownum &= 5000;
CREATE TABLE T_NEW (ID, TIME) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE))
AS SELECT ID, TIME FROM T;
RENAME T TO T_OLD;
RENAME T_NEW TO T;
优点:方法简单易用,由于采用DDL语句,不会产生UNDO,且只产生少量REDO,效率相对较高,而且建表完成后数据已经在分布到各个分区中了。
不足:对于数据的一致性方面还需要额外的考虑。由于几乎没有办法通过手工锁定T表的方式保证一致性,在执行CREATE TABLE语句和RENAME T_NEW TO T语句直接的修改可能会丢失,如果要保证一致性,需要在执行完语句后对数据进行检查,而这个代价是比较大的。另外在执行两个RENAME语句之间执行的对T的访问会失败。
适用性:适用于修改不频繁的表,在闲时进行操作,表的数据量不宜太大。 2.2方法二:使用交换分区的方法
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO t
SELECT Rownum, SYSDATE - Rownum FROM Dba_Objects WHERE Rownum &= 5000;
CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (MAXVALUE));
ALTER TABLE T_NEW EXCHANGE PARTITION P1 WITH TABLE T;
RENAME T TO T_OLD;
RENAME T_NEW TO T;
优点:只是对数据字典中分区和表的定义进行了修改,没有数据的修改或复制,效率最高。如果对数据在分区中的分布没有进一步要求的话,实现比较简单。在执行完RENAME操作后,可以检查T_OLD中是否存在数据,如果存在的话,直接将这些数据插入到T中,可以保证对T插入的操作不会丢失。
不足:仍然存在一致性问题,交换分区之后RENAME T_NEW TO T之前,查询、更新和删除会出现错误或访问不到数据。如果要求数据分布到多个分区中,则需要进行分区的SPLIT操作,会增加操作的复杂度,效率也会降低。
适用性:适用于包含大数据量的表转到分区表中的一个分区的操作。应尽量在闲时进行操作。 2.3方法三:Oracle9i以上版本,利用在线重定义功能
CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE);
INSERT INTO T
SELECT ROWNUM, SYSDATE - ROWNUM FROM DBA_OBJECTS WHERE ROWNUM &= 5000;
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(USER, 'T');
PL/SQL 过程已成功完成。
CREATE TABLE T_NEW (ID NUMBER PRIMARY KEY, TIME DATE) PARTITION BY RANGE (TIME)
(PARTITION P1 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P2 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P3 VALUES LESS THAN (TO_DATE('', 'YYYY-MM-DD')),
PARTITION P4 VALUES LESS THAN (MAXVALUE));
表已创建。
EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'T', 'T_NEW');
PL/SQL 过程已成功完成。
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'T', 'T_NEW');
PL/SQL 过程已成功完成。
优点:保证数据的一致性,在大部分时间内,表T都可以正常进行DML操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性,对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约束,可以做到切换完成后不再需要任何额外的管理操作。
不足:实现上比上面两种略显复杂。
适用性:适用于各种情况。
这里只给出了在线重定义表的一个最简单的例子,详细的描述和例子可以参考下面两篇文章。
Oracle的在线重定义表功能:
Oracle的在线重定义表功能(二):2.4把一个已存在数据的大表改成分区表:
第一种(表不是太大):
--1.把原表改名:
rename xsb1 to xsb2;
--2.创建分区表:
CREATE TABLE xsb1
PARTITION BY LIST (c_test)
(PARTITION xsb1_p1 VALUES (1),
PARTITION xsb1_p2 VALUES (2),
PARTITION xsb1_p0 VALUES (default))
nologging AS SELECT * FROM xsb2;
--3.将原表上的触发器、主键、索引等应用到分区表上;
--4.删除原表:
drop table xsb2;
第二种(表很大):
--1. 创建分区表:
CREATE TABLE x PARTITION BY LIST (c_test) [range ()]
(PARTITION p0 VALUES [less than ](1) tablespace tbs1,
PARTITION p2 VALUES (2) tablespace tbs1,
PARTITION xsb1_p0 VALUES ([maxvalue]default))
AS SELECT * FROM xsb2 [where 1=2];
--2. 交换分区
alter table x exchange partition p0 with tab
--3. 原表改名
alter table bsvcbusrundatald rename to x0;
--4. 新表改名
alter table x rename
--5. 删除原表
drop table x0;
--6. 创建新表触发器和索引
create index ind_busrundata_lp on bsvcbusrundatald(。。。) local tablespace tbs_brd_
1. 规划原大表中数据分区的界限,原则上将原表中近期少量数据复制至另一表;
2. 暂停原大表中的相关触发器;
3. 删除原大表中近期数据;
4. 改名原大表名称;
5. 创建分区表;
6. 交换分区;
7. 重建相关索引及触发器(先删除之再重建).
参考脚本:
select count(*) from t1 where recdate&sysdate-2;
create table x2 nologging as select * from t1 where recdate&trunc(sysdate-2);
alter triger trg_t1
delete t1 where recdate&sysdate-2;
rename t1 to x1;
create table t1 [nologging] partition by range(recdate)
(partition pbefore values less than (trunc(sysdate-2)),
partition pmax values less than (maxvalue))
as select * from x1 where 1=2;
alter table t1 exchange partition pbefore with table x1;
alter table t1 exchange partition pmax with table x2;
drop table x2;
--重建触发器
drop table x1;
&3.分区的方法:
范围分区Range散列分区Hash列表分区List组合范围-散列分区Range-Hash组合范围-列表分区Range-List
可对索引和表分区。全局索引只能按范围分区,但可以将其定义在任何类型的分区或非分区表上。通常全局索引比局部索引需要更多的维护。
一般组建局部索引,以便反映其基础表的结构。它与基础表是等同分区的,即它与基础表在同样的列上分区,创建同样数量的分区或子分区,设置与基础表相对应的同样的分区边界。对局部索引而言,当维护活动影响分区时,会自动维护索引分区。这保证了索引与基础表之间的等同分区。
关于范围分区Range:
要想将行映射到基于列值范围的分区,就使用范围分区方法。当数据可以被划分成逻辑范围时如年度中的月份,这种类型的分区就有用了。当数据在整个范围中能被均等地划分时性能最好。如果靠范围的分区会由于不均等的划分而导致分区在大小上明显不同时,就需要考虑其他的分区方法。
关于散列分区Hash:
如果数据不那么容易进行范围分区,但为了性能和管理的原因又想分区时,就使用散列分区方法。散列分区提供了一种在指定数量的分区中均等地划分数据的方法。基于分区键的散列值将行映射到分区中。创建和使用散列分区会给你提供了一种很灵活的放置数据的方法,因为你可以通过在I/O 驱动器之间播撒(摘掉)这些均等定量的分区,来影响可用性和性能。
关于列表分区List:
当你需要明确地控制如何将行映射到分区时,就使用列表分区方法。可以在每个分区的描述中为该分区列指定一列离散值,这不同于范围分区,在那里一个范围与一个分区相关,这也不同于散列分区,在那里用户不能控制如何将行映射到分区。列表分区方法是特意为遵从离散值的模块化数据划分而设计的。范围分区或散列分区不那么容易做到这一点。进一步说列表分区可以非常自然地将无序的和不相关的数据集进行分组和组织到一起。
与范围分区和散列分区所不同,列表分区不支持多列分区。如果要将表按列分区,那么分区键就只能由表的一个单独的列组成,然而可以用范围分区或散列分区方法进行分区的所有的列,都可以用列表分区方法进行分区。
关于组合范围-散列分区:
范围和散列技术的组合,首先对表进行范围分区,然后用散列技术对每个范围分区再次分区。给定的范围分区的所有子分区加在一起表示数据的逻辑子集。
关于组合范围-列表分区:
范围和列表技术的组合,首先对表进行范围分区,然后用列表技术对每个范围分区再次分区。与组合范围-散列分区不同的是,每个子分区的所有内容表示数据的逻辑子集,由适当的范围和列表分区设置来描述。
注意:创建或更改分区表时可以指定行移动子句,即ENABLE ROW MOVEMENT 或者DISABLE ROW MOVEMENT ,当其键被更改时,该子句启用或停用将行迁移到一个新的分区。默认值为DISABLE ROW MOVEMENT。
如果表中预期的数据量较大,通常都需要考虑使用分区表,确定使用分区表后,还要确定什么类型的分区(range partition、hash partition、list partition等)、分区区间大小等。分区的创建最好与程序有某种默契,比如创建一个分区表,按自然月份定义分区的,但程序却在查询时默认的开始时间与结束时间是:当前日期-30至当前日期,比如当天是9.18号,那查询条件被产生为8.18-9.18,结果分区后并不没有大幅提高性能。为此将程序的查询日期做了调整,按自然月查询,系统的负载小了很多。4.补充资料
从Oracle8.0开始支持表分区(MSSQL2005开始支持表分区)。
Oracle9i 分区能够提高许多应用程序的可管理性、性能与可用性。分区可以将表、索引及索引编排表进一步划分,从而可以更精细地对这些数据库对象进行管理和访问。Oracle 提供了种类繁多的分区方案以满足所有的业务需要。另外,由于在 SQL 语句中是完全透明的,所以分区可以用于几乎所有的应用程序。
分区表允许将数据分成被称为分区甚至子分区的更小的更好管理的块。索引也可以这么分区。每个分区可以被单独管理,可以不依赖于其他分区而单独发挥作用,因此提供了一个更有利于可用性和性能的结构。
分区可以提高可管理性、性能与可用性,从而给各种各样的应用程序带来极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还能够在很大程度上简化日常管理任务。分区还使数据库设计人员和管理员能够解决尖端应用程序带来的最难的问题。分区是建立上亿万字节数据系统或需要极高可用性系统的关键工具。
在多CPU配置环境下,如果打算使用并行执行,则分区提供了另一种并行的方法。通过给表或索引的不同分区分配不同的并行执行服务器,就可以并行执行对分区表和分区索引的操作。
表或索引的分区和子分区都共享相同的逻辑属性。例如表的所有分区或子分区共享相同的列和约束定义,一个索引的分区或子分区共享相同的索引选项。然而它们可以具有不同的物理属性如表空间。
尽管不需要将表或索引的每个分区或子分区放在不同的表空间,但这样做更好。将分区存储到不同的表空间能够:
减少数据在多个分区中冲突的可能性可以单独备份和恢复每个分区控制分区与磁盘驱动器之间的映射对平衡I/O 负载是重要的改善可管理性可用性和性能
分区操作对现存的应用和运行在分区表上的标准DML 语句来说是透明的。但是可以通过在DML 中使用分区扩展表或索引的名字来对应用编程,使其利用分区的优点。
可以使用SQL*Loader、Import 和Export 工具来装载或卸载分区表中的数据。这些工具都是支持分区和子分区的。4.1分区技术能够提高数据库的可管理性:
使用分区技术,维护操作可集中于表的特定部分。例如,数据库管理员可以只对表的一部分做备份,而不必对整个表做备份。对整个数据库对象的维护操作,可以在每个分区的基础上进行,从而将维护工作分解成更容易管理的小块。
分区技术提高可管理性的一个典型用法是支持数据仓库中的‘滚动视窗’加载进程。假设数据库管理员每周向表中加载新数据。该表可以是范围分区,以便每个分区包含一周的数据。加载进程只是简单地添加新的分区。添加一个新分区的操作比修改整个表效率高很多,因为数据库管理员不需要修改任何其他分区。从分区后的表中去除数据也是一样。你只要用一个很简便快捷的数据字典操作删掉一个分区,而不必发出使用大量资源和调动所有要删除的数据的 ‘DELETE’ 命令。4.2分区技术能够提高数据库的性能:
由于减少了所检查或操作的数据数量,同时允许并行执行,Oracle9i 的分区功能提供了性能上的优势。这些性能包括:
分区修整:分区修整是用分区技术提高性能的最简单最有价值的手段。分区修整常常能够将查询性能提高几个数量级。例如,假定应用程序中有包含定单历史记录的定单表,该表用周进行了分区。查询一周的定单只需访问该定单表的一个分区。如果该定单表包含两年的历史记录,这个查询只需要访问一个而不是一百零四个分区。该查询的执行速度因为分区修整而有可能快一百倍。分区修整能与所有其他 Oracle 性能特性协作。Oracle 公司将把分区修整技术与索引技术、连结技术和并行访问方法一起联合使用。分区智能联接:分区功能可以通过称为分区智能联接的技术提高多表联接的性能。当两个表要联接在一起,而且每个表都用联接关键字来分区时,就可以使用分区智能联接。分区智能联接将大型联接分解成较小的发生在各个分区间的联接,从而用较少的时间完成全部联接。这就给串行和并行的执行都能带来显著的性能改善。更新和删除的并行执行:分区功能能够无限地并行执行 UPDATE、DELETE 与 MERGE 语句。当访问分区或未分区的数据库对象时Oracle 将并行处理 SELECT 与 INSERT 语句。当不使用位图索引时,也可以对分区或未分区的数据库对象并行处理 UPDATE、DELETE 和 MERGE 语句。为了对有位图索引的对象并行处理那些操作,目标表必须先分区。这些 SQL 语句的并行执行可以大大提高性能,特别是提高 UPDATE 与 DELETE 或 MERGE 操作涉及大量数据时的性能。4.3分区技术提高可用性:
分区的数据库对象具有分区独立性。该分区独立性特点可能是高可用性战略的一个重要部分,例如,如果分区表的分区不能用,但该表的所有其他分区仍然保持在线并可用。那么这个应用程序可以继续针对该分区表执行查询和事务处理,只要不是访问那个不可用的分区,数据库操作仍然能够成功运行。 数据库管理员可以指定各分区存放在不同的表空间里,从而让管理员独立于其它表分区针对每个分区进行备份与恢复操作。 还有,分区功能可以减少计划停机时间。性能由于分区功能得到了改善,使数据库管理员在相对较小的批处理窗口完成大型数据库对象的维护工作。
将普通表转换成分区表有4种方法:&&
&&&&&&&1. Export/import&method&&
&&&&&&&2. Insert&with&a&subquery&method&&&&&&&& 3. Partition&exchange&method&&&&&&&& 4. DBMS_REDEFINITION&&&&&&&&&&&
&&&&select&*&from&t_user_info_&&
&&&&drop&table&t_phone_test&&&
create&table&t_phone_test(phone,part)&nologging&&partition&by&list(part)&&
partition&p0&values('0'),&&
partition&p1&values('1'),&&
partition&p2&values('2'),&&
partition&p3&values('3'),&&
partition&p4&values('4'),&&
partition&p5&values('5'),&&
partition&p6&values('6'),&&
partition&p7&values('7'),&&
partition&p8&values('8'),&&
partition&p9&values('9')&&
select&user_mobile&phone,substr(user_mobile,-1,1)&part&&
from&t_user_info_&&
select&*&from&t_phone_test&partition(p0);&&
select&*&from&t_phone_test&where&part='0';&&
&&&&&这种方法只是对数据字典中分区和表的定义进行了修改,没有数据的修改或复制,效率最高。适用于包含大数据量的表转到分区表中的一个分区的操作。尽量在闲时进行操作。&&
交换分区的操作步骤如下:&&
&&&&&1.&创建分区表,假设有2个分区,P1,P2.&&
&&&&&2.&创建表A存放P1规则的数据。&&
&&&&&3.&创建表B&存放P2规则的数据。&&
&&&&&4.&用表A&和P1&分区交换。&把表A的数据放到到P1分区&&
&&&&&5.&用表B&和p2&分区交换。&把表B的数据存放到P2分区。&&
create&table&t_phone_test_0&nologging&&
select&user_mobile&phone,substr(user_mobile,-1,1)&part&&
from&t_user_info_test&where&substr(user_mobile,-1,1)='0';&&
select&count(*)&from&t_phone_test&where&part='0';&&
select&count(*)&from&t_user_info_test&where&substr(user_mobile,-1,1)='0';&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_0;&&
delete&from&&&t_phone_test_0;&&
select&count(*)&from&t_phone_test&where&part='0';&&
select&count(*)&from&t_phone_test_0;&&
insert&into&t_phone_test(phone,part)&values('','0');&&
insert&into&t_phone_test_0(phone,part)&values('','1');&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_0;&&
delete&from&t_phone_test_0&where&part='1';&&
alter&table&t_phone_test&merge&partitions&p0,p1&into&partition&p0;&&
select&count(*)&from&t_phone_test&where&part='0';&&
select&count(*)&from&t_phone_test&where&part='1';&&
select&count(*)&&from&t_phone_test&partition(p0);&&
select&count(*)&&from&t_phone_test&partition(p1);&&
&alter&table&t_phone_test&&add&partition&p10&values(default);&&
insert&into&t_phone_test(phone,part)&values('','10');&&
insert&into&t_phone_test(phone,part)&values('','20');&&
select&*&from&&&
alter&table&t_phone_test&drop&partition&p10;&&
&alter&table&t_phone_test&&add&partition&p10&values(&'10');&&
alter&table&t_phone_test&exchange&partition&p10&with&table&t_phone_test_10;&&
alter&table&T_PHONE_TEST_10&modify&PART&VARCHAR2(2);&&
alter&table&t_phone_test&merge&partitions&p0,p10&into&partition&p0;&&
&&partition&P0&values&('10',&'0')&&
&&&&tablespace&APP_DATAN&&
&&&&pctfree&10&&
&&&&initrans&1&&
&&&&maxtrans&255&&
&&&&storage&&
&&&&&&initial&1M&&
&&&&&&next&1M&&
&&&&&&minextents&1&&
&&&&&&maxextents&unlimited&&
&&&&&&pctincrease&0&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_10;&&&&&
alter&table&t_phone_test&drop&partition&p0;&&
alter&table&t_phone_test&&add&partition&p0&values(&'0');&&&&&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_10;&&&&&
drop&table&t_phone_test_10&&&
create&table&t_phone_test_10&nologging&&
select&user_mobile&phone,substr(user_mobile,-2,2)&part&&
from&t_user_info_test&where&substr(user_mobile,-2,2)='10';&&
drop&table&t_phone_test_0&&&
create&table&t_phone_test_0&nologging&&&
select&&phone,substr(phone,-1,1)&part&&
from&t_phone_test_10;&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_0;&&
select&*&from&t_phone_test_10;&&
select&count(*)&&from&t_phone_test&partition(p0);&&
select&count(*)&&from&t_phone_test&partition(p10);&&
select&count(*)&from&t_phone_test_10;&&
select&count(*)&from&t_phone_test_0;&&
select&substr('123456',-1,1),substr('123456',-2,2),substr('123456',-3,2)&from&&&
1.创建分区表&&
drop&table&t_phone_test&&&
create&table&t_phone_test(phone,part)&nologging&&partition&by&list(part)&&
partition&p0&values('0'),&&
partition&p1&values('1'),&&
partition&p2&values('2'),&&
partition&p3&values('3'),&&
partition&p4&values('4'),&&
partition&p5&values('5'),&&
partition&p6&values('6'),&&
partition&p7&values('7'),&&
partition&p8&values('8'),&&
partition&p9&values('9')&&
select&user_mobile&phone,substr(user_mobile,-1,1)&part&&
from&t_user_info_&&
select&count(*)&&from&t_phone_test&partition(p0);&&
select&count(*)&&from&t_phone_test&partition(p10);&&
select&count(*)&from&t_phone_test_10;&&
select&count(*)&from&t_phone_test_0;&&
2.创建基表&&
drop&table&t_phone_test_10&&&
create&table&t_phone_test_10&nologging&&
select&&phone,substr(phone,-2,2)&part&&
from&t_phone_test&where&substr(phone,-2,2)='10';&&
select&count(*)&from&t_phone_test_10;&&
alter&table&T_PHONE_TEST_10&modify&PART&VARCHAR2(2);&&
3.添加分区&&
alter&table&t_phone_test&&add&partition&p10&values(&'10');&&&&&&
select&count(*)&&from&t_phone_test&partition(p10);&&
4.交换分区&&
alter&table&t_phone_test&exchange&partition&p10&with&table&t_phone_test_10;&&&&&
select&count(*)&&from&t_phone_test&partition(p10);&&
5.合并分区&&
alter&table&t_phone_test&merge&partitions&p0,p10&into&partition&p0;&&
select&count(*)&&from&t_phone_test&partition(p0);&&
&&partition&P0&values&('10',&'0')&&
&&&&tablespace&APP_DATAN&&
&&&&pctfree&10&&
&&&&initrans&1&&
&&&&maxtrans&255&&
&&&&storage&&
&&&&&&initial&1M&&
&&&&&&next&1M&&
&&&&&&minextents&1&&
&&&&&&maxextents&unlimited&&
&&&&&&pctincrease&0&&
6.交换分区&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_10;&&&&
select&count(*)&&from&t_phone_test&partition(p0);&&
select&count(*)&from&t_phone_test_10;&&
6.删除分区&和添加分区&&
alter&table&t_phone_test&&drop&partition&p0;&&
alter&table&t_phone_test&&add&partition&p0&values('0');&&
7.筛选数据&&
drop&table&t_phone_test_0&&&
create&table&t_phone_test_0&nologging&&
select&&phone,substr(phone,-1,1)&part&&
from&t_phone_test_10&where&substr(phone,-1,1)='0';&&
select&count(*)&from&t_phone_test_0;&&
8.交换分区&&
alter&table&t_phone_test&exchange&partition&p0&with&table&t_phone_test_0;&&&&
select&count(*)&&from&t_phone_test&partition(p0);&&select&count(*)&from&t_phone_test_0;&&
&&&&& Oracle数据库中,有两种类型的分区索引,全局索引和本地索引,其中本地索引又可以分为本地前缀索引和本地非前缀索引。下面就分别看看每种类型的索引各自的特点。全局索引以整个表的数据为对象建立索引,索引分区中的索引条目既可能是基于相同的键值但是来自不同的分区,也可能是多个不同键值的组合。全局索引既允许索引分区的键值和表分区键值相同,也可以不相同。全局索引和表之间没有直接的联系,这一点和本地索引不同。SQL& create table orders (&&&& order_no&&&&& number,&&&& part_no&&&&&& varchar2(40),&&&& ord_date&&&&& date&&&& )&&&& partition by range (ord_date)&&&&& (partition Q1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')),&&&&&& partition Q2 values less than (TO_DATE('01-JUL-1999','DD-MON-YYYY')),&&&&&& partition Q3 values less than (TO_DATE('01-OCT-1999','DD-MON-YYYY')),&&&&&& partition Q4 values less than (TO_DATE('01-JAN-2000','DD-MON-YYYY'))&&&&& )&&&& ;Table created.SQL& create index orders_global_1_idx&&&& on orders(ord_date)&&&&& global partition by range (ord_date)&&&&&& (partition GLOBAL1 values less than (TO_DATE('01-APR-1999','DD-MON-YYYY')),&&&&&&& partition GLOBAL2 values less than (TO_DATE('01-JUL-1999','DD-MON-YYYY')),&&&&&&& partition GLOBAL3 values less than (TO_DATE('01-OCT-1999','DD-MON-YYYY')),&&&&&&& partition GLOBAL4 values less than (MAXVALUE)&&&&&& )&&&& ;Index created.SQL& create index orders_global_2_idx&&&& on orders(part_no)&&&&& global partition by range (part_no)&&&&&& (partition IND1 values less than (555555),&&&&&&& partition IND2 values less than (MAXVALUE)&&&&&& )&&&& ;Index created.从上面的语句可以看出,全局索引和表没有直接的关联,必须显式的指定maxvalue值。假如表中新加了分区,不会在全局索引中自动增加新的分区,必须手工添加相应的分区。SQL& alter table orders add partition Q5 values less than (TO_DATE('01-APR-2000','DD-MON-YYYY'));Table altered.SQL& select TABLE_NAME, PARTITION_NAME from dba_tab_partitions where table_name='ORDERS';TABLE_NAME&&&&&&&&&&&&&&&&&&&& PARTITION_NAME------------------------------ ------------------------------ORDERS&&&&&&&&&&&&&&&&&&&&&&&& Q1ORDERS&&&&&&&&&&&&&&&&&&&&&&&& Q2ORDERS&&&&&&&&&&&&&&&&&&&&&&&& Q3ORDERS&&&&&&&&&&&&&&&&&&&&&&&& Q4ORDERS&&&&&&&&&&&&&&&&&&&&&&&& Q5SQL& select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_global_1_idx');INDEX_NAME&&&&&&&&&&&&&&&&&&&& PARTITION_NAME------------------------------ ------------------------------ORDERS_GLOBAL_1_IDX&&&&&&&&&&& GLOBAL1ORDERS_GLOBAL_1_IDX&&&&&&&&&&& GLOBAL2ORDERS_GLOBAL_1_IDX&&&&&&&&&&& GLOBAL3ORDERS_GLOBAL_1_IDX&&&&&&&&&&& GLOBAL4使用全局索引,索引键值必须和分区键值相同,这就是所谓的前缀索引。Oracle不支持非前缀的全局分区索引,如果需要建立非前缀分区索引,索引必须建成本地索引。SQL& create index orders_global_2_idx& 2& on orders(part_no)& 3&& global partition by range (order_no)& 4&&& (partition IND1 values less than (555555),& 5&&&& partition IND2 values less than (MAXVALUE)& 6&&& )& 7& ;&global partition by range (order_no)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *ERROR at line 3:ORA-14038: GLOBAL partitioned index must be prefixed接下来再来看看本地分区。本地索引的分区和其对应的表分区数量相等,因此每个表分区都对应着相应的索引分区。使用本地索引,不需要指定分区范围因为索引对于表而言是本地的,当本地索引创建时,Oracle会自动为表中的每个分区创建独立的索引分区。创建本地索引不必显式的指定maxvalue值,因为为表新添加表分区时,会自动添加相应的索引分区。create index orders_local_1_idxon orders(ord_date)&local& (partition LOCAL1,&& partition LOCAL2,&& partition LOCAL3,&& partition LOCAL4& );Index created.SQL& select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_local_1_idx');INDEX_NAME&&&&&&&&&&&&&&&&&&&& PARTITION_NAME------------------------------ ------------------------------ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL1ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL2ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL3ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL4SQL& alter table orders add partition Q5 values less than (TO_DATE('01-APR-2000','DD-MON-YYYY'));Table altered.SQL& select INDEX_NAME, PARTITION_NAME from dba_ind_partitions where index_name=upper('orders_local_1_idx');INDEX_NAME&&&&&&&&&&&&&&&&&&&& PARTITION_NAME------------------------------ ------------------------------ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL1ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL2ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL3ORDERS_LOCAL_1_IDX&&&&&&&&&&&& LOCAL4ORDERS_LOCAL_1_IDX&&&&&&&&&&&& Q5这里系统已经自动以和表分区相同的名字自动创建了一个索引分区。同理,删除表分区时相对应的索引分区也自动被删除。本地索引和全局索引还有一个显著的差别,就是上面提到的,本地索引可以创建成本地非前缀型,而全局索引只能是前缀型。SQL& create index orders_local_2_idx&&&& on orders(part_no)&&&&& local&&&&&& (partition LOCAL1,&&&&&&& partition LOCAL2,&&&&&&& partition LOCAL3,&&&&&&& partition LOCAL4)&&&& ;Index created.SQL& select INDEX_NAME, PARTITION_NAME, HIGH_VALUE from dba_ind_partitions&&&& where index_name=upper('orders_local_2_idx');INDEX_NAME&&&&&&&&&&&&&&&&&&&& PARTITION_NAME&&&&&&&&&&&&&&&& HIGH_VALUE------------------------------ ------------------------------ ---------------------------------------------------------ORDERS_LOCAL_2_IDX&&&&&&&&&&&& LOCAL1&&&&&&&&&&&&&&&&&&&&&&&& TO_DATE('
00:00:00', 'SYYYY-MM-DD HH24:MI:SS', &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'NLS_CALENDAR=GREGORIA'ORDERS_LOCAL_2_IDX&&&&&&&&&&&& LOCAL2&&&&&&&&&&&&&&&&&&&&&&&& TO_DATE('
00:00:00', 'SYYYY-MM-DD HH24:MI:SS', &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'NLS_CALENDAR=GREGORIA'ORDERS_LOCAL_2_IDX&&&&&&&&&&&& LOCAL3&&&&&&&&&&&&&&&&&&&&&&&& TO_DATE('
00:00:00', 'SYYYY-MM-DD HH24:MI:SS',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'NLS_CALENDAR=GREGORIA'ORDERS_LOCAL_2_IDX&&&&&&&&&&&& LOCAL4&&&&&&&&&&&&&&&&&&&&&&&& TO_DATE('
00:00:00', 'SYYYY-MM-DD HH24:MI:SS',&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 'NLS_CALENDAR=GREGORIA'从上面的输出可以看出,虽然索引的键值是part_no,但索引分区的键值仍然和表的分区键值相同,即ord_date,也即是所谓的非前缀型索引。最后,再引用一个例子说明前缀索引和非前缀索引的应用。假设有一个使用DATE列分区的大表。我们经常使用一个VARCHAR2列(VCOL)进行查询,但这个列并不是表的分区键值。有两种可能的方法来访问VCOL列的数据,一是建立基于VCOL列的本地非前缀索引,&&&&&&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&& -------&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& -------&&&&&&&&&&& |&&&&&& |&&&&&&&& (10 more&&&&&&&&&&&&&&& |&&&&&&& |Values:&&&& A..&&&& Z..&& partitions here)&&&&&&&&&&& A..&&&&& Z.. 另一种是建立基于VCOL列的全局索引,&&&&&&&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&&& -------&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& -------&&&&&&&&&&&& |&&&&&& |&&&&&&&& (10 more&&&&&&&&&&&&&&& |&&&&&&& |Values:&&&&& A..&&&& D..&& partitions here)&&&&&&&&&&& T..&&&&& Z.. 可以看出,如果能够保证VCOL列值的唯一性,全局索引将会是最好的选择。如果VCOL列值不唯一,就需要在本地非前缀索引的并行查询和全局索引顺序查询以及高昂的维护代价之间做出选择。
造成ORA-12560: TNS: 协议适配器错误的问题的原因可能有如下三个:1.监听服务没有起起来。windows平台个一如下操作:开始---程序---管理工具---服务}

我要回帖

更多关于 天涯明月刀大叔捏脸 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信