6

出于某种原因,当我尝试在一个大表(4000 万〜记录)上进行 CTAS(创建表作为选择)时,我在 v$session 18活动会话中看到我的 sql 语句。

当我试图提示优化器使用更少的 CPU 时

create table table_name parallel (degree 2) as 
       select * from large_table;

我看到 6 个活动会话。

在 3 级时,我看到8个活动会话。我尝试了默认学位,但它也创建了 18 个会话。

之前在代码中,在执行 CREATE TABLE 语句之前,我在会话中更改了一些属性:

alter session set workarea_size_policy = manual;
alter session set hash_area_size = 1048576000;

我想在 1 个会话中创建表,我该怎么做?

谢谢 !

4

1 回答 1

8

在 CTAS 语句的 select 子句中使用 NO_PARALLEL 提示 。另请参阅有关并行提示的注释

create table t as
select /*+ NO_PARALLEL */ * 
from large_table;

调查与测试:

SQL*Plus 版本和 Oracle 数据库版本:

SQL*Plus: Release 11.1.0.6.0 - Production on Fri Sep 21 11:56:58 2012

Copyright (c) 1982, 2007, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

我使用两个不同的 sqlplus 进程通过不同的服务名称连接到同一个数据库。一份正在运行的 sqlplus 副本将用于执行 CTAS。sqlplus 的另一个副本将用于查询会话数。

在其他任何事情之前获取会话计数和结果的查询:

SQL> select service_name, count(*)
  2  from v$session
  3  where username = 'ME'
  4  group by service_name
  5  order by service_name;

SERVICE_NAME                                                       COUNT(*)
---------------------------------------------------------------- ----------
aaaaaa2                                                                   1
aaaaaa3                                                                   1

创建large_table

SQL> create table LAO as select * from all_objects;

Table created.

SQL> exec dbms_stats.gather_table_stats(user, 'LAO');

PL/SQL procedure successfully completed.

SQL> create table large_table parallel 4 as
  2  select N.N, LAO.*
  3  from LAO
  4  cross join (select level as N from dual connect by level <= 400) N
  5  /

Table created.

SQL> select to_char(count(*), 'fm999,999,999')
  2  from large_table;

TO_CHAR(COUN
------------
42,695,200

由于large_table是用 来创建的parallel 4,一个简单的 CTAS 默认为 4 个工作进程,CTAS:

create table t as
select * from large_table;

会议:

SERVICE_NAME                                                       COUNT(*)
---------------------------------------------------------------- ----------
aaaaaa2                                                                   5
aaaaaa3                                                                   1

现在,noparallel表格选项。(创建一个默认情况下没有 DML 并行计划的表,但并行性large_table会导致 CTAS 并行运行。)

drop table t;
create table t noparallel as
select * from large_table;

会话(SYS$BACKGROUND 在最后一个查询结束时出现,然后一直停留。我相信如果在一定时间内不需要它,它就会死掉。):

SERVICE_NAME                                                       COUNT(*)
---------------------------------------------------------------- ----------
SYS$BACKGROUND                                                            1
aaaaaa2                                                                   5
aaaaaa3                                                                   1

select 子句中的 NO_PARALLEL 提示确实有效:

drop table t;
create table t as
select /*+ NO_PARALLEL */ * from large_table;

会议:

SERVICE_NAME                                                       COUNT(*)
---------------------------------------------------------------- ----------
SYS$BACKGROUND                                                            1
aaaaaa2                                                                   1
aaaaaa3                                                                   1

最后一个 CTAS,其中创建的表默认使用多个进程,但在 CTAS 期间不会:

drop table t;
create table t parallel 4 as
select /*+ NO_PARALLEL */ * from large_table;

会议:

SERVICE_NAME                                                       COUNT(*)
---------------------------------------------------------------- ----------
SYS$BACKGROUND                                                            1
aaaaaa2                                                                   1
aaaaaa3                                                                   1
于 2012-09-21T18:49:23.237 回答