NULL列时,如何使得IS NULL或者IS NOT NULL可以使用索引来提高查询效率
虽然我们一直强调在进行数据库设计的时候,要尽量设置所有的列为NOT NULL,这样的最直接的好处就是假如这个列上有一个索引,那么对这个表进行COUNT(*)统计的时候(假设这个表只有这一列有索引,并且索引全扫描比 全表扫描COST低),ORACLE会直接对这个列的索引进行一个快速扫描得到COUNT结果,而不是进行一个全表扫描。虽然B*TREE索引是不存储 NULL值的,但是因为你定义列的时候明确的告诉ORACLE这一列是NOT NULL的,所以ORACLE会知道扫描索引得到的结果跟全表扫描得到的结果是一致的(因为列的值都是NOT NULL的,也就是说列的所有
遭遇ITL死锁
转载自www.ixdba.com:一个增量刷新的程序,看哪些记录发生变化了(使用TRIGGER记录),就在远端把相应的记录删除,再把本地的数据insert过去。因为数据量比较大,而单一的delete和insert对资源的使用率也不高,就准备多开几个程序一起刷新,来加快刷新速度。其中有一个中间表,只会插入和删除,不会更新,就想当然的把PCTFREE设置为0以节省空间。结果发生了死锁。piner版主对这种类型的死锁进行了深入的分析,这里只进行转载。[@more@]1、什么是ITLITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,用来记录该块所有发
11G R2中的并行执行,dbms_parallel_execute
在以前我们处理大数据量的时候,一般机器硬件都足够强悍,单线程的处理怎么也消耗不了多少的系统资源,而整个处理的过程又比较慢,这个时候并行就出现了。 并行可以通过ORACLE的PARALLEL来指定和执行,而在11G R2版本中,这个功能得到了加强,ORACLE推出了一个dbms_parallel_execute包,专门来处理这些内容。这个包其实原理也比较简 单:首先是把数据分成一个个CHUNK,然后指定并行度来同时执行这些任务。就类似手工的按照主键、ROWID或者数据的日期等等进行并行处理类似。下面 来看看这个咚咚怎么使用[@more@]使用dbms_parallel_
ORA_ROWSCN与按照commit时间对记录进行排序
问题的提出:在并发的环境下,每个sql先执行的不一定先提交,因此想如何才能按照事务提交的顺序来对记录进行排序而不是按照sql执行的时间。[@more@]先来说说sysdate或者systimestamp,如果系统中使用这样的列来记录每个记录最后提交的时间,那是错误的。而且很多人认为这个时间如果设置为default值,那么记录的就是sql执行的时间,其实也是错误的。oracle 10.2 版本的concept第388页有这样一句话“Default values are included as part of an INSERT statement before the statement is parsed.”因此可以看到,把列的default值设置为缺省
如果在一个过程中得到上级调用它的过程的信息
pub上有网友问到了这个问题,也有人回答了这个问题,自己做个测试,权当做个记录吧。[@more@]创建被调用的过程T1:CREATE OR REPLACE PROCEDURE T1 IS L_OWNER VARCHAR2(100); L_NAME VARCHAR2(100); L_LINENO NUMBER; L_CALLER_T VARCHAR2(100);BEGIN OWA_UTIL.WHO_CALLED_ME(OWNER => L_OWNER, NAME => L_NAME, LINENO => L_LINENO, CALLER_T => L_CALLER_T); DBMS_OUTPUT.PUT_LINE('t1'); DBMS_OUTPUT.PUT_LINE(L_OWNER
自动为新建的表创建同义词
问题提出:为了控制用户权限,给某些用户只有查询系统的权限,但是这样带来的维护麻烦是每次系统创建了新的表,都需要给查询用户对这个表的查询权限授权,然后查询用户使用的时候不方便,要加上用户的前缀才能使用。这里提供一个自动为新创建的表进行授权和创建同义词的办法。[@more@] 解决的办法就是使用系统触发器,当在一个schema上创建一个表的时候,就使用动态语句来执行授权和创建同义词的语句。问题的难点是如果单纯使用execute immedite来创建同义词,则会报权限不足,怎么都搞不定。后来搜索了一下,tom提供了下面的方法,
oracle的会话如何自杀?
问题提出:pub上有网友提出了一个会话如何自杀,因为一个会话是不能杀死自己的,如果直接执行alter system kill session 来杀死自己,则报错如下:SQL> select sid,serial# from v$session where sid in (select sid from v$mystat); SID SERIAL#---------- ---------- 855 27SQL> alter system kill session '855,27';alter system kill session '855,27'*ERROR at line 1:ORA-00027: cannot kill current session[@more@]那来看一下如何把kill session的任务扔给job,让job充当另一个会话来杀掉自己:CREA
生成脚本,得到所有表的外键约束,然后删除并重建这些约束
仅做记录,可以得到所有的外键约束,生成创建和删除这些约束的脚本,在数据库管理中有点用处[@more@]CREATE OR REPLACE PROCEDURE GENERATE_FK ISCURSOR C ISSELECT TABLE_NAMEFROM USER_CONSTRAINTSWHERE CONSTRAINT_NAME IN(SELECT DISTINCT R_CONSTRAINT_NAMEFROM USER_CONSTRAINTSWHERE R_CONSTRAINT_NAME IS NOT NULL)ORDER BY TABLE_NAME;BEGINFOR R IN C LOOPDBMS_OUTPUT.PUT_LINE('table_name : ' || R.TABLE_NAME);DBMS_OUTPUT.PUT_LINE('drop script : ');FOR R1 IN (SELECT 'alter table ' || TABLE_NAME || ' drop constraint
pl/sql developer中关于TIMESTAMP显示格式的疑问和学习
ORACLE中的TIMESTAMP数据类型可能大家用的都比较少,所以即使最简单的一个查询返回的结果也会搞不清楚到底这个时间是什么时间点。比如:27-1月 -08 12.04.35.877000 上午 这个时间到底是几点呢?中午12:04分,那就错了,其实使用to_char函数转换后得到如下结果:2008-01-27 00:04:35:877000 说明这个时间是凌晨的00:04分,而不是中午的12:04分。 [@more@]发生这个问题的原因如下:首先来看一个实验:SELECT TO_CHAR(TO_DATE('2008-01-29 00:05:10', 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh:mi:ss am') FROM DUAL首先把一个00:05分的时间
记录一个行列转换
昨天在pub问了个行列转换的问题,有大侠提出了解决办法,拷贝作来,做个记录吧。实现了把其中两列分别与其他列进行组合,然后把一行数据转化成两行,转换后的数据量是现在的两倍。[@more@]SQL> select empno, ename, job from emp where deptno = 10; EMPNO ENAME JOB---------- ---------- --------- 7782 CLARK MANAGER 7839 KING PRESIDENT 7934 MILLER CLERKSQL> select b.empno, decode(a.rn,1,b.ename,b.job) info from 2 (select rownum rn from dual connect by rownum <= 2)
记录一个简陋的根据statspack查找哪段时间事务量最大的脚本
生产系统上的STATSPACK是15分钟一次的,但是一天这么多次都发邮件出来也没很大必要,因此每天凌晨把前一整天的报告发出来,有时候发现了TOP 5的等待事件中出现了以前没出现过的异常,也不大好找这个等待集中发生在哪里。因此,先从事务量下手,写个脚本来统计哪个时间段内的事务量最大,当然,这应该是个系列,回头碰见问题了再慢慢写其他统计量最大的脚本。[@more@]其实这些脚本都可以从statspack的spreport的脚本中稍微整理得到,记录在次以方便以后使用:DECLARE --可以找到输出的事务量最大的对应的那个statspack的endid,然后 --在