oracle建表语句分页语句效率

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&ORACLE分页查询SQL语法——最高效的分页
ORACLE分页查询SQL语法——最高效的分页
author:XIAOHUI_LIAO&&
--1:无ORDER BY排序的写法。(效率最高)
--(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!)
& FROM (SELECT ROWNUM AS rowno,
WHERE hire_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&
AND ROWNUM &= <font color="#)
table_alias
&WHERE table_alias.rowno &= <font color="#;
--2:有ORDER BY排序的写法。(效率最高)
--(经过测试,此方法随着查询范围的扩大,速度也会越来越慢哦!)
& FROM (SELECT tt.*, ROWNUM AS rowno
FROM (& SELECT t.*
&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&
WHERE hire_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&
ORDER BY create_time DESC, emp_no)
WHERE ROWNUM &= <font color="#)
table_alias
&WHERE table_alias.rowno &= <font color="#;
=================================================================================
=======================垃圾但又似乎很常用的分页写法==========================
=================================================================================
--3:无ORDER BY排序的写法。(建议使用方法1代替)
--(此方法随着查询数据量的扩张,速度会越来越慢哦!)
FROM (SELECT ROWNUM AS rowno,
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')) table_alias
&WHERE table_alias.rowno &= <font color="# AND table_alias.rowno &= <font color="#;
--TABLE_ALIAS.ROWNO&
between 10 and 100;
--4:有ORDER BY排序的写法.(建议使用方法2代替)
--(此方法随着查询范围的扩大,速度会越来越慢哦!)
FROM (SELECT tt.*, ROWNUM AS rowno
FROM (& SELECT
&&&&&&&&&&&&&&&&&&&
FROM k_task t
&&&&&&&&&&&&&&&&&&
WHERE flight_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&
ORDER BY fact_up_time,
flight_no)
tt) table_alias
&WHERE table_alias.rowno BETWEEN <font color="# AND <font color="#;
--5另类语法。(有ORDER BY写法)
--(语法风格与传统的SQL语法不同,不方便阅读与理解,为规范与统一标准,不推荐使用。)
WITH partdata AS
SELECT ROWNUM AS rowno,
FROM (& SELECT
&&&&&&&&&&&&&&&&&&&
FROM k_task t
&&&&&&&&&&&&&&&&&&
WHERE flight_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&
ORDER BY fact_up_time,
flight_no) tt
WHERE ROWNUM &= <font color="#)
FROM partdata
&WHERE rowno &= <font color="#;
--6另类语法 。(无ORDER BY写法)
WITH partdata AS
SELECT ROWNUM AS rowno,
FROM k_task t
WHERE flight_date BETWEEN TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
AND TO_DATE ('',
'yyyymmdd')
&&&&&&&&&&
AND ROWNUM &= <font color="#)
FROM partdata
&WHERE rowno &= <font color="#;
yangtingkun分析:
& --- from
Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用。
分页查询格式:
& FROM (SELECT a.*, ROWNUM rn
FROM (SELECT *
&&&&&&&&&&&&&&&&&
FROM table_name)
WHERE ROWNUM &= <font color="#)
&WHERE rn &= <font color="#
其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM
&= 40和RN &= 21控制分页查询的每页的范围。
上面给出的这个分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE
ROWNUM &= 40这句上。
选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM &=
40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM &=
40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:
FROM (SELECT a.*, ROWNUM rn
FROM (SELECT *
&&&&&&&&&&&&&&&&&
FROM table_name)
&WHERE rn BETWEEN <font color="# AND <font style="font-size: 10pt" color="#
对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。
这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE
40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。
而第二个查询语句,由于查询条件BETWEEN 21 AND
40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。
上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。
这里就不对包含排序的查询进行说明了,下一篇文章会通过例子来详细说明。
下面简单讨论一下多表联合的情况。
对于最常见的等值表连接查询,CBO一般可能会采用两种连接方式NESTED LOOP和HASH JOIN(MERGE
JOIN效率比HASH JOIN效率低,一般CBO不会考虑)。在这里,由于使用了分页,因此指定了一个返回的最大记录数,NESTED
LOOP在返回记录数超过最大值时可以马上停止并将结果返回给中间层,而HASH JOIN必须处理完所有结果集(MERGE
JOIN也是)。那么在大部分的情况下,对于分页查询选择NESTED
LOOP作为查询的连接方法具有较高的效率(分页查询的时候绝大部分的情况是查询前几页的数据,越靠后面的页数访问几率越小)。
因此,如果不介意在系统中使用HINT的话,可以将分页的查询语句改写为:
FROM (SELECT a.*, ROWNUM rn
FROM (SELECT *
&&&&&&&&&&&&&&&&&
FROM table_name) a
WHERE ROWNUM &= <font color="#)
&WHERE rn &= <font style="font-size: 10pt" color="#
发表评论:
TA的最新馆藏当前位置:&>&&>&
oracle中update语句的性能优化
发布时间:编辑:
本文介绍下,oracle数据库中update语句的语法与原理,以及提高oracle更新效率的多种方法,即优化update语句性能的方法,供大家学习参考。
本节主要内容:
Oracle update语句的性能优化
一、update语句的语法与原理
单表:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
复制代码 代码示例:
update t_join_situation set join_state='1'whereyear='2011'
更新年度为&2011&的数据的join_state字段为&1&。如果更新的字段加了索引,更新时会重建索引,更新效率会慢。
多表关联,并把一个表的字段值更新到另一个表中的字段去:
复制代码 代码示例:
update 表a set a.字段1 = (select b.字段1 from 表b where a.字段2=b.字段2) where exists(select 1 from 表b where a.字段2=b.字段2)&
oracle的更新语句不通MSSQL那么简单易写,就算写出来了,但执行时可能会报
这是由于set哪里的子查询查出了多行数据值,oracle规定一对一更新数据,所以提示出错。要解决这样必须保证查出来的值一一对应。
Update语句的原理是先根据where条件查到数据后,如果set中有子查询,则执行子查询把值查出来赋给更新的字段,执行更新。
复制代码 代码示例:
update 表a set a.字段1 = (select b.字段1 from 表b where a.字段2=b.字段2) where exists(select 1 from 表b where a.字段2=b.字段2)
。查表a的所有数据,循环每条数据,验证该条数据是否符合exists(select 1 from 表b where a.字段2=b.字段2)条件,如果是则执行(select b.字段1 from 表b where a.字段2=b.字段2)查询,查到对应的值更新a.字段1中。关联表更新时一定要有exists(select 1 from 表b where a.字段2=b.字段2)这样的条件,否则将表a的其他数据的字段1更新为null值。
二、提高oracle更新效率的各种解决方案
1,标准update语法
当需要更新的表是单个或者被更新的字段不需要关联其他表带过来,则最后选择标准的update语句,速度最快,稳定性最好,并返回影响条数。
如果where条件中的字段加上索引,那么更新效率就更高。但对需要关联表更新字段时,update的效率就非常差。
2,inline view更新法
inline view更新法就是更新一个临时建立的视图。如:
复制代码 代码示例:
update (select a.join_state as join_state_a,b.join_state as join_state_b
from t_join_situation a, t_people_info b where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000') set join_state_a=join_state_b
括号里通过关联两表建立一个视图,set中设置好更新的字段。这个解决方法比写法较直观且执行速度快。但表B的主键一定要在where条件中,并且是以&=&来关联被更新表,否则报一下错误:
3,merge更新法
merge是oracle特有的语句,语法如下:
复制代码 代码示例:
MERGE INTO table_name 1
USING (table|view|sub_query) alias2
ON (join condition)
WHEN MATCHED THEN
&&& UPDATE table_name
&&& SET col1 = col_val1,
&& col2= col2_val
WHEN NOT MATCHED THEN
&&& INSERT (column_list) VALUES (column_values);
原理分析:在alias2中Select出来的数据,每一条都跟alias1进行 ON (join condition)的比较,如果匹配,就进行更新的操作(Update),如果不匹配,就进行插入操作(Insert)。执行merge不会返回影响的行数。Merge语句的写法比较繁琐,并且最多只能两个表关联,复杂的语句用merge更新法将力不从心且效率差。
4,快速游标更新法
for cr in (查询语句) loop &-循环
&& --更新语句(根据查询出来的结果集合)
--结束循环
oracle支持快速游标,不需要定义直接把游标写到for循环中,这样就方便了我们批量更新数据。再加上oracle的rowid物理字段(oracle默认给每个表都有rowid这个字段,并且是唯一索引),可以快速定位到要更新的记录上。
复制代码 代码示例:
for cr in (select a.rowid,b.join_state from t_join_situation a,t_people_info b
where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000') loop
update t_join_situation set join_state=cr.join_state where
rowid = cr.
使用快速游标的好处很多,可以支持复杂的查询语句,更新准确,无论数据多大更新效率仍然高,但执行后不返回影响行数。
标准update语法
单表更新或较简单的语句采用使用此方案更优。
inline view更新法
两表关联且被更新表通过关联表主键关联的,采用此方案更优。
merge更新法
两表关联且被更新表不是通过关联表主键关联的,采用此方案更优。
快速游标更新法
多表关联且逻辑复杂的,采用此方案更优。
实时测试的速度:
复制代码 代码示例:
--48466条数据
update (select a.join_state as join_state_a,b.join_state as join_state_b
from t_join_situation a, t_people_info b where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000'
) set join_state_a=join_state_b
update t_join_situation a set a.join_state=(select b.join_state from t_people_info b
where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000')
whereexists (select1from t_people_info b
where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000')
for cr in (select a.rowid,b.join_state from t_join_situation a,t_people_info b
where a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000') loop
update t_join_situation set join_state=cr.join_state where
rowid = cr.
mergeinto t_join_situation a
using t_people_info b
on (a.people_number=b.people_number
and a.year='2011'and a.city_number='M00000'and a.town_number='M51000')
whenmatchedthenupdateset a.join_state=b.join_state
与 oracle中update语句的性能优化 有关的文章
本文标题:
本页链接:
12345678910
12345678910Oracle实现分页查询的SQL语法汇总
投稿:shichen2014
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Oracle实现分页查询的SQL语法,非常实用的功能,需要的朋友可以参考下
本文实例汇总了Oracle实现分页查询的SQL语法,整理给大家供大家参考之用,详情如下:
1.无ORDER BY排序的写法。(效率最高)
经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!
sql语句如下:
FROM (Select ROWNUM AS ROWNO, T.*
from k_task T
where Flight_date between to_date('', 'yyyymmdd') and
to_date('', 'yyyymmdd')
AND ROWNUM &= 20) TABLE_ALIAS
WHERE TABLE_ALIAS.ROWNO &= 10;
2.有ORDER BY排序的写法。(效率最高)
经过测试,此方法随着查询范围的扩大,速度也会越来越慢!
sql语句如下:
FROM (SELECT TT.*, ROWNUM AS ROWNO
FROM (Select t.*
from k_task T
where flight_date between to_date('', 'yyyymmdd') and
to_date('', 'yyyymmdd')
ORDER BY FACT_UP_TIME, flight_no) TT
WHERE ROWNUM &= 20) TABLE_ALIAS
where TABLE_ALIAS.rowno &= 10;
3.无ORDER BY排序的写法。(建议使用方法1代替)
此方法随着查询数据量的扩张,速度会越来越慢!
sql语句如下:
FROM (Select ROWNUM AS ROWNO, T.*
from k_task T
where Flight_date between to_date('', 'yyyymmdd') and
to_date('', 'yyyymmdd')) TABLE_ALIAS
WHERE TABLE_ALIAS.ROWNO &= 20
AND TABLE_ALIAS.ROWNO &= 10;
TABLE_ALIAS.ROWNO between 10 and 100;
4.有ORDER BY排序的写法.(建议使用方法2代替)
此方法随着查询范围的扩大,速度也会越来越慢!
sql语句如下:
FROM (SELECT TT.*, ROWNUM AS ROWNO
FROM (Select *
from k_task T
where flight_date between to_date('', 'yyyymmdd') and
to_date('', 'yyyymmdd')
ORDER BY FACT_UP_TIME, flight_no) TT) TABLE_ALIAS
where TABLE_ALIAS.rowno BETWEEN 10 AND 20;
5.另类语法。(有ORDER BY写法)
该语法风格与传统的SQL语法不同,不方便阅读与理解,为规范与统一标准,不推荐使用。此处贴出代码供大家参考之用。
sql语句如下:
With partdata as(
SELECT ROWNUM AS ROWNO, TT.* FROM (Select *
from k_task T
where flight_date between to_date('', 'yyyymmdd') and
to_date('', 'yyyymmdd')
ORDER BY FACT_UP_TIME, flight_no) TT
WHERE ROWNUM &= 20)
Select * from partdata where rowno &= 10;
6.另类语法 。(无ORDER BY写法)
With partdata as(
Select ROWNUM AS ROWNO, T.*
From K_task T
where Flight_date between to_date('', 'yyyymmdd') and
To_date('', 'yyyymmdd')
AND ROWNUM &= 20)
Select * from partdata where Rowno &= 10;
相信本文所述代码能够对大家有一定的参考借鉴价值。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具如题,现在有20个单位,在分页中,我想第一页只显示前五个单位的所有数据,后一页显示后五个单位的所有数据,请问高手们该怎么写这条sql语句。
--------------------------------------
from (select t.*, rownum rn from scott.emp t) where rn between 1 and 5;如果是最后一页 就是 where rn between 16 and 20;
--------------------------------------
引用 1 楼 u 的回复:select *
from (select t.*, rownum rn from scott.emp t) where rn between 1 and 5;如果是最后一页 就是 where rn between 16 and 20;首先谢谢您,但是这个不是这样就可以解决的,因为这个单位表示和另一张主表进行left join的,然后主要是在他们left join 以后获取这个单位的前五个单位。
--------------------------------------
引用 2 楼 chanjacken910 的回复:Quote: 引用 1 楼 u 的回复:select *
from (select t.*, rownum rn from scott.emp t) where rn between 1 and 5;如果是最后一页 就是 where rn between 16 and 20;首先谢谢您,但是这个不是这样就可以解决的,因为这个单位表示和另一张主表进行left join的,然后主要是在他们left join 以后获取这个单位的前五个单位。那你给点create 和insert ,来点实际数据 看下你到底要怎么个搞法?
--------------------------------------
楼主没有诚意啊,贴出create和insert语句

我要回帖

更多关于 oracle建表语句 的文章

 

随机推荐