对于数据库中表的数据的 Web 显示,如果没有展示顺序的需要,而且因为满足条件的记录如 此之多,就不得不对数据进行分页处理。常常用户并不是对所有数据都感兴趣的,或者大部分情 况下,他们只看前几页。

通常有以下两种分页技术可供选择。

1
2
3
4
5
6
7
Select * from (
Select rownum rn,t.* from table t)
Where rn>&minnum and rn<=&maxnum
或者
Select * from (
Select rownum rn,t.* from table t rownum<=&maxnum)
Where rn>&minnum
看似相似的分页语句,在响应速度上其实有很大的差别。来看一个测试过程,首先创建一个测试表。

1
SQL> create table test as select * from dba_objects;
并反复地插入相同数据。

1
SQL> insert into test select * from test;
最后,查询该表,可以看到该表的记录数约为 80 万条。

1
2
3
4
SQL> select count (*) from test

COUNT (*)

 831104

现在分别采用两种分页方式,在第一种分页方式中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SQL> select * from (
2 select rownum rn,t.* from test t)
3 where rn>0 and rn <=50;

已选择50行。
已用时间: 00: 00: 01.03

Execution Plan

0       SELECT  STATEMENT Optimizer=CHOOSE (Cost=10 Card=65 Bytes=12350)
1    0    VIEW  (Cost=10 Card=65 Bytes=12350)
2    1      COUNT
3    2        TABLE  ACCESS ( FULL )  OF  'TEST'  (Cost=10 Card=65 Bytes=5590)

Statistics

       0  recursive calls
       0  db block gets
   10246  consistent gets
       0  physical reads
       0  redo  size
       ……

可以看到,这种方式查询第一页的一致性读有 10246 个,结果满足了,但是效率是很差的,如果采用第二种方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SQL> select * from (
2 select rownum rn,t.* from test t
3 where rownum <=50)
4 where rn>0;

已选择50行。
已用时间: 00: 00: 01.00

Execution Plan

0       SELECT  STATEMENT Optimizer=CHOOSE (Cost=10 Card=50 Bytes=9500)
1    0    VIEW  (Cost=10 Card=50 Bytes=9500)
2    1      COUNT  (STOPKEY)
3    2        TABLE  ACCESS ( FULL )  OF  'TEST'  (Cost=10 Card=65 Bytes=5590)

Statistics

       0  recursive calls
       0  db block gets
      82  consistent gets
       0  physical reads
       0  redo  size
       ……

得到了同样的结果,一致性读只有 82 个,从以上的例子可以看到,通过把 rownum 引入到第 二层,却得到了一个完全不一样的执行计划,注意在执行计划中的 stopkey,它是 8i 引入的新操 作,这种操作专门为提取 Top n 的需求做了优化。

从上面的例子可以再想到,因为 stopkey 的功能影响到了分页的一致性读的多少,会不会越往后翻页速度就越慢呢?事实也的确如此,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SQL> select * from (
2 select rownum rn,t.* from test t
3 where rownum <=10000)
4 where rn>9950;

已选择50行。
已用时间: 00: 00: 01.01

Statistics

       0  recursive calls
       0  db block gets
    2616  consistent gets
       0  physical reads
       0  redo  size
      ……

选择靠后一点的数据时,逻辑读开始变大,当选择到最后几页时,一致性读已经与上面的相似了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SQL> select * from (
2 select rownum rn,t.* from test t
3 where rownum <=800000)
4 where rn>799950;

已选择50行。
已用时间: 00: 00: 01.03

Statistics

       0  recursive calls
       0  db block gets
   10242  consistent gets
       0  physical reads
       0  redo  size
       ……

不过,所幸的是,大部分的用户只看开始 5%的数据,而没有兴趣看最后面的数据,通过第二种改良的分页技术,可以方便快速地显示前面的数据,而且不会让用户感觉到慢。
————————————————
版权声明:本文为CSDN博主「sunansheng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sunansheng/article/details/52586697

通过nbu进行sqlserver备份的实施过程中的几点思考
1、通过全备+增备的方式进行备份,需要考虑数据量的大小。
2、备份配置异常的原因包括网络防火墙、备份脚本的配置参数、操作系统的认证策略、数据库备份用户的权限等原因。
3、检查备份异常的方式主要是查看数据库的运行日志
4、备份整体实施过程的顺利,主要取决于基础信息的完整,主要靠相关干系人的配合,细节问题的处理,主要依赖备份软件官网上的资料,相关问题的资料也能体现出产品的成熟度,从这一点来说,NBU算是比较成熟的产品,但是因为资源的原因,在目前仅仅作为整库的备份,没有部署方便的恢复环境,帮助实现更多价值。

Oracle 12c ADG备库执行sql报错ORA-22303、ORA-16000、ORA-06508、ORA-06512

2020-03-03 15:34:32.830 [job-81740957] INFO  SingleTableSplitUtil - split pk [sql=SELECT * FROM ( SELECT xxx FROM xxx.xxx SAMPLE (0.1)  WHERE (xxx IS NOT NULL)  ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 15 ORDER by xxx ASC] is running...
2020-03-03 15:34:32.969 [job-81740957] ERROR JobContainer - Exception when job run
com.alibaba.datax.common.exception.DataXException: Code:[DBUtilErrorCode-07], Description:[读取数据库数据失败. 请检查您的配置的 column/table/where/querySql或者向 DBA 寻求帮助.].  - 执行的SQL为:SELECT * FROM ( SELECT xxx FROM xxx.xxx SAMPLE (0.1)  WHERE (xxx IS NOT NULL)  ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM <= 15 ORDER by xxx ASC 具体错误信息为:ORA-22303: 未找到类型 "SYS"."WRR$_REPLAY_DEP_GRAPH"
ORA-16000: 数据库或可插入数据库是以只读访问方式打开的
ORA-06508: PL/SQL: 无法找到正在调用 : "SYS.DBMS_WORKLOAD_REPLAY" 的程序单元
ORA-06512: 在 "SYS.DBMS_WRR_STATE", line 4
ORA-06512: 在 "SYS.DBMS_RANDOM", line 91
 - java.sql.SQLException: ORA-22303: 未找到类型 "SYS"."WRR$_REPLAY_DEP_GRAPH"
ORA-16000: 数据库或可插入数据库是以只读访问方式打开的
ORA-06508: PL/SQL: 无法找到正在调用 : "SYS.DBMS_WORKLOAD_REPLAY" 的程序单元
ORA-06512: 在 "SYS.DBMS_WRR_STATE", line 4
ORA-06512: 在 "SYS.DBMS_RANDOM", line 91

主库

sqlplus / as sysdba
alter session set container=pdb_name;
grant select on "SYS"."WRR$_REPLAY_DEP_GRAPH" to username;

策划提出需求,能否禁止对表的更新操作,首先想到的就是触发器,实际测试后脚本如下

   1、要求对表的行进行删除和更新的限制:

create or replace trigger noudeleteorupdatefortabla_A
  before update or delete
  on table_a
  for each row
declare
  -- local variables here
begin
 if updating  then
  raise_application_error(-20000,'不能对table_A表进行update操作');
  elsif deleting then
   raise_application_error(-20000,'不能对table_A表进行delete操作'); 
  end if;
end;



2、要求对表的字段进行删除和更新的限制:

create or replace trigger nouDeloUpFortabla_A_object_id
  before update or delete
  on table_a
  for each row
declare
  -- local variables here
begin
 if updating('OBJECT_ID')  then
  raise_application_error(-20000,'不能对table_A表的object_id进行update操作');
 END IF;
 if DELETING then  ----删除操作是对行的,不能指定字段
   raise_application_error(-20000,'不能对table_A表进行delete操作');
 END IF;
end;

  DECLARE
    j     number;
    s_sql varchar2(5000);
  BEGIN
    FOR j IN 1 .. 1000000 LOOP
      s_sql := 'insert into collect_data
    select t.test_start_date,
           t.test_end_date,
           t.test_qq,
           t.test_name,
           DQMP_PROBLEM_DATA_SEQ.NEXTVAL,
           t.dept,
           t.password_old1,
           t.password_old2,
           t.password_modify_date
      from test1 t';
      execute immediate s_sql;
      commit;
    END LOOP;
  END;

————————————————
版权声明:本文为CSDN博主「czmchen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/czmchen/article/details/6525133