d 0 e 2 表2 A B c 0 e 4 合并两个表除去重复的数据(以表2的数据为主),我们将会得到以下的表:
A B a 1 b 0 c 0 d 0 e 4 select A,B from 表1 where A not in(select A from 表2) union select A,B from 表2 巧用一条SQL 实现其它进制到十进制转换
发布时间:2007.09.25 04:57 来源:赛迪网 作者:han
问:怎样实现ORACLE中用一条SQL实现其它进制到十进制的转换? 答:具体示例如下:
-----二进制转换十进制----------------- select sum(data1) from (select substr('1101', rownum, 1) * power (2, length('1101') - rownum) data1 from dual connect by rownum <= length('1101')) -----八进制转换十进制----------------- select sum(data1) from (select substr('1101', rownum, 1) * power (8, length('1101') - rownum) data1 from dual connect by rownum <= length('1101')) -----十六进制转换十进制----------------- select sum(data1) from (select (CASE upper(substr('2D', rownum, 1)) WHEN 'A' THEN '10' WHEN 'B' THEN '11' WHEN 'C' THEN '12' WHEN 'D' THEN '13' WHEN 'E' THEN '14' WHEN 'F' THEN '15' ELSE substr('2D', rownum, 1) END) * power(16, length('2D') - rownum) data1 from dual connect by rownum <= length('2D')) 注释:
对其它进制可以根据例子将power的底数改成相应的进制就可以了。 本文只是一个例子,大家可以把它封装成一个通用函数进行实用。
大家在试的时候将里面相应的其它进制的数值换成自己的数据就可以了(有多处)。
实例讲解如何才能让你的SQL运行得更快 (1)
发布时间:2008.01.22 04:52 来源:赛迪网 作者:10633
很多人在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS)中表现得尤为明显。
笔者在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。
在对它们进行适当的优化后,其运行速度有了明显地提高! 下面我将从这三个方面分别进行总结:
为了更直观地说明问题,所有实例中的SQL运行时间均经过测试,不超过1秒的均表示为(< 1秒)。----
测试环境: 主机:HP LH II---- 主频:330MHZ---- 内存:128兆---- 操作系统:Operserver5.0.4---- 数据库:Sybase11.0.3 一、不合理的索引设计
例:表record有620000行,试看在不同的索引下,下面几个 SQL的运行情况: 1.在date上建有一非个群集索引
select count(*) from record where date > '19991201' and date < '19991214'and amount >2000 (25秒) select date ,sum(amount) from record group by date(55秒) select count(*) from record where date > '19990901' and place in ('BJ','SH') (27秒) 分析:date上有大量的重复值,在非群集索引下,数据在物理上随机存放在数据页上,在范围查找时,必须执行一次表扫描才能找到这一范围内的全部行。
2.在date上的一个群集索引
select count(*) from record where date > '19991201' and date < '19991214' and amount >2000 (14秒) select date,sum(amount) from record group by date(28秒) select count(*) from record where date > '19990901' and place in ('BJ','SH')(14秒) 分析:在群集索引下,数据在物理上按顺序在数据页上,重复值也排列在一起,因而在范围查找时,可以先找到这个范围的起末点,且只在这个范围内扫描数据页,避免了大范围扫描,提高了查询速度。
3.在place,date,amount上的组合索引
select count(*) from record where date > '19991201' and date < '19991214' and amount >2000 (26秒) select date,sum(amount) from record group by date(27秒) select count(*) from record where date > '19990901' and place in ('BJ, 'SH')(< 1秒) 分析:这是一个不很合理的组合索引,因为它的前导列是place,第一和第二条SQL没有引用place,因此也没有利用上索引;第三个SQL使用了place,且引用的所有列都包含在组合索引中,形成了索引覆盖,所以它的速度是非常快的。
4.在date,place,amount上的组合索引
select count(*) from record where date > '19991201' and date < '19991214' and amount >2000(< 1秒) select date,sum(amount) from record group by date(11秒) select count(*) from record where date > '19990901' and place in ('BJ','SH')(< 1秒) 分析:这是一个合理的组合索引。它将date作为前导列,使每个SQL都可以利用索引,并且在第一和第三个SQL中形成了索引覆盖,因而性能达到了最优。
5.总结:
缺省情况下建立的索引是非群集索引,但有时它并不是最佳的;合理的索引设计要建立在对各种查询的分析和预测上。
一般来说:
①.有大量重复值、且经常有范围查询(between, >,< ,>=,< =)和order by、group by发生的列,可考虑建立群集索引;
②.经常同时存取多列,且每列都含有重复值可考虑建立组合索引;
③.组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。 二、不充份的连接条件:
例:表card有7896行,在card_no上有一个非聚集索引,表account有191122行,在account_no上有一个非聚集索引,试看在不同的表连接条件下,两个SQL的执行情况:
select sum(a.amount) from account a, card b where a.card_no = b.card_no(20秒) select sum(a.amount) from account a, card b where a.card_no = b.card_no and a.account_no=b.account_no(< 1秒) 分析:>在第一个连接条件下,最佳查询方案是将account作外层表,card作内层表,利用card上的索引,其I/O次数可由以下公式估算为:
外层表account上的22541页+(外层表account的191122行*内层表card上对应外层表第一行所要查找的3页)=595907次I/O
在第二个连接条件下,最佳查询方案是将card作外层表,account作内层表,利用account上的索引,其I/O次数可由以下公式估算为:外层表card上的1944页+(外层表card的7896行*内层表account上对应外层表每一行所要查找的4页)= 33528次I/O
可见,只有充份的连接条件,真正的最佳方案才会被执行。 总结: