有表 a,b,c ,表a表b记录数比较大几百万条,表c只有几百条
表a id为主键 adddate作普通索引
=====================================================
id adddate sort1 sort2 ......
1 2009-5-12 00:00:01 aaaa bbbb
2 2009-5-12 10:00:01 eeee aaaa
3 2009-5-11 20:01:01 cccc bbbb
4 2009-5-10 10:20:01 bbbb eeee
5 2009-5-9 10:20:01 aaaa eeee
6 2009-5-8 10:20:01 1111 cccc
...
======================================================
表b id作普通索引 表a与表b的关系是一对一关系,通过id号关联.
==========================================
id content adddate
1 564565 2009-5-12 00:00:02
2 435435 2009-5-12 00:00:03
3 543543 2009-5-12 10:00:01
4 apopep 2009-5-11 20:01:01
.....
==========================================
表c sort作普通索引 表a中的sort1字段或sort2字段皆有可能与sort字段关联
==========================================
sort stat unit aaaa 1 a
bbbb 1 b
cccc 1 c
eeee 2 e
==========================================以上三表实现关联查询:
select * from a inner join b on a.id=b.id inner join c on (a.sort1=c.sort or a.sort2=c.sort) where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi') order by adddate desc
但效率不高,
后来改后
select * from a inner join b on a.id=b.id inner join c on a.sort1=c.sort where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi') union all
select * from a inner join b on a.id=b.id inner join c on a.sort2=c.sort where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
使用union all连接,快了很多.但在后面加上 order by adddate desc就慢得不得了
不知有什么好的优惠方法,请指点!
表a id为主键 adddate作普通索引
=====================================================
id adddate sort1 sort2 ......
1 2009-5-12 00:00:01 aaaa bbbb
2 2009-5-12 10:00:01 eeee aaaa
3 2009-5-11 20:01:01 cccc bbbb
4 2009-5-10 10:20:01 bbbb eeee
5 2009-5-9 10:20:01 aaaa eeee
6 2009-5-8 10:20:01 1111 cccc
...
======================================================
表b id作普通索引 表a与表b的关系是一对一关系,通过id号关联.
==========================================
id content adddate
1 564565 2009-5-12 00:00:02
2 435435 2009-5-12 00:00:03
3 543543 2009-5-12 10:00:01
4 apopep 2009-5-11 20:01:01
.....
==========================================
表c sort作普通索引 表a中的sort1字段或sort2字段皆有可能与sort字段关联
==========================================
sort stat unit aaaa 1 a
bbbb 1 b
cccc 1 c
eeee 2 e
==========================================以上三表实现关联查询:
select * from a inner join b on a.id=b.id inner join c on (a.sort1=c.sort or a.sort2=c.sort) where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi') order by adddate desc
但效率不高,
后来改后
select * from a inner join b on a.id=b.id inner join c on a.sort1=c.sort where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi') union all
select * from a inner join b on a.id=b.id inner join c on a.sort2=c.sort where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi') and a.adddate<=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
使用union all连接,快了很多.但在后面加上 order by adddate desc就慢得不得了
不知有什么好的优惠方法,请指点!
解决方案 »
- 关于sqlplus的一个登录问题?
- Oracle数据库都用什么管理?PL/SQL Dev工具版本是否要跟Oracle版本对应?
- 这条SQL语句该怎么写?
- 请问Oracle 9i 中有没有判断内容为非数字的判断函数吗?!
- 关于使用 sqlplus 登录问题
- 如何在存储过程里实现将最后一个标点符号换成想要的符号
- 明天开始Oracle,请问要买什么样子的盘啊,现在是哪个版本啊?
- 如何在一个字段中同时插入两个关联对象?
- 一个简单的问题
- oracle9i pro*c on Windows2000 server 请教高手
- power designer 打开一个pdm文件怎么没数据啊
- 從A表查找數據,字段卻在B表
from a
inner join b on a.id = b.id
inner join c on (a.sort1 = c.sort or a.sort2 = c.sort)
where a.adddate > to_date('2008-12-31 00:00', 'yyyy-mm-dd hh24:mi')
and a.adddate < to_date('2009-05-16 23:59', 'yyyy-mm-dd hh24:mi')
order by adddate desc
或者用inner join
看一下解释计划,还是不对的话加上hint试试
如下语句:加ordered是强制执行计划先访问c表,然后nl嵌套循环走a表sort1或sort2索引访问a,再访问b
select x.id, x.adddate, x.sort1, x.sort2
from (
select /*+ ordered*/a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort1
union all
select /*+ ordered*/a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort2
) x
order by x.adddate desc
2.尽管union all方式a,b,c表访问了两遍,但此种情况比使用or实现效率高
3.如果a表查询的adddate范围涉及到的记录很少,则可不需建sort1, sort2索引,且取消上一sql的提示信息
即:
select x.id, x.adddate, x.sort1, x.sort2
from (
select a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort1
union all
select a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort2
) x
order by x.adddate desc
4.避免查询用*,这样会使得sql访问数据库字典得到表相应字段,增加了额外开销
5.个人认为你的表设计有问题,a,b两个表完全等价于一张表,可一张表实现
(select * from a where a.adddate<... and a.adddate>... order by a.adddate)
如下语句:加ordered是强制执行计划先访问c表,然后nl嵌套循环走a表sort1或sort2索引访问a,再访问b
select x.id, x.adddate, x.sort1, x.sort2
from (
select /*+ ordered*/a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort1
union all
select /*+ ordered*/a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort2
) x
order by x.adddate desc
2.尽管union all方式a,b,c表访问了两遍,但此种情况比使用or实现效率高
3.如果a表查询的adddate范围涉及到的记录很少,则可不需建sort1, sort2索引,且取消上一sql的提示信息
即:
select x.id, x.adddate, x.sort1, x.sort2
from (
select a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort1
union all
select a.id, a.adddate, a.sort1, a.sort2
from c, a, b
where a.adddate>=to_date('2009-01-01 00:00','yyyy-mm-dd hh24:mi')
and a.adddate <=to_date('2009-05-15 23:59','yyyy-mm-dd hh24:mi')
and a.id = b.id
and a.sort1 = c.sort2
) x
order by x.adddate desc
4.避免查询用*,这样会使得sql访问数据库字典得到表相应字段,增加了额外开销
5.个人认为你的表设计有问题,a,b两个表完全等价于一张表,可一张表实现
select *
from a
inner join b on a.id = b.id
inner join c on a.sort1 = c.sort
where a.adddate >= to_date('2009-01-01 00:00', 'yyyy-mm-dd hh24:mi')
and a.adddate <= to_date('2009-05-15 23:59', 'yyyy-mm-dd hh24:mi')
union all
select *
from a
inner join b on a.id = b.id
inner join c on a.sort2 = c.sort
where a.adddate >= to_date('2009-01-01 00:00', 'yyyy-mm-dd hh24:mi')
and a.adddate <= to_date('2009-05-15 23:59', 'yyyy-mm-dd hh24:mi')
)abc1你是慢在排序上面。有2种解决方案。1,先看看你的总数据量有多少,如果百万的话,你用order by当然会慢了,你想想啊,先查询出百万数据,然后再一个个排序,不慢才怪呢?就不要排序了。2,oracle排序用的是大池,也就是larger pool,你数据量在数十万以上排序的话,非常消耗资源,你多给larger pool分配点内存吧!
1.a 表和b 表实际使用中是一对多关系,只是此查询以一对一为主所以只说一对一关系.
2.查询中只读取a b c表中的几个字段,没有使用"*".不好意思这里写了用"*".
3.不显示所有的百万条记录,只显示时间段内的部分记录.有分页的.即该查询外另套分页语句
4.b.id不是主键,原因是实际表中不是一对一关系,所以没有使用主键.
5.sort1和sort2已做了normal索引,不好意思,没有标出来.