Oracle序列的NEXTVAL不是按顺序吗?

编程语言 2026-07-09

我有一个简单的序列,如下:

CREATE SEQUENCE my_sequence
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;

我试图插入某些东西,并且像这样使用这个序列:

INSERT INTO table1(col0, col1, col2, col3, col4, col5)
SELECT my_sequence.NEXTVAL, col1, col2, col3, col4, col5
FROM (
    SELECT tt.col1,
    tt.col2,
    tt.col3,
    tt.col4,
    sx.col5,
    FROM table2 tt
    LEFT JOIN table3 sx ON tt.col6 = sx.col6
    WHERE sx.col5 LIKE 'P%'
    ORDER BY tt.col1 ASC
);

现在,当我查看table1的内容时,它们的排序并非如预期。如果按col1排序,col0的数字显示为:

col0   col1     col2
1        1      ...
2        2
5        3
6        4
7        5
8        6
11       7
9        8
10       9
12       10
3        11
4        12
...

如果我清空表并重新运行,顺序又会再次不同。

为什么会这样?我该怎么做才能强制排序?

解决方案

如果你运行并行DML(必须显式开启,或在Autonomous Database上使用MEDIUM或 HIGH服务),每组在进入并发插入进程之前都会被正确排序,但它们会被并行发送到插入进程(P->P),因此一个可能在另一个之前完成,顺序就会随机。

ADMIN@o23_tp> select * from dbms_xplan.display_cursor(format=>'basic +parallel');

PLAN_TABLE_OUTPUT
___________________________________________________________________________________________________
EXPLAINED SQL STATEMENT:
------------------------
INSERT /*+ parallel(2) */ INTO employee_registry (emp_id, first_name,
last_name, hire_date, salary, dept_name)   SELECT emp_id_seq.NEXTVAL,
first_name, last_name, hire_date, salary, dept_name   FROM (
SELECT c.first_name,              c.last_name,
c.hire_date,              c.salary,              d.dept_name       FROM
candidates c       LEFT JOIN departments d ON c.dept_code = d.dept_code
      WHERE d.dept_name LIKE 'P%'       ORDER BY c.last_name ASC   )

Plan hash value: 3347350506

------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name              |    TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                      |                   |        |      |            |
|   1 |  PX COORDINATOR                       |                   |        |      |            |
|   2 |   PX SEND QC (RANDOM)                 | :TQ10002          |  Q1,02 | P->S | QC (RAND)  |
|   3 |    INDEX MAINTENANCE                  | EMPLOYEE_REGISTRY |  Q1,02 | PCWP |            |
|   4 |     PX RECEIVE                        |                   |  Q1,02 | PCWP |            |
|   5 |      PX SEND RANGE                    | :TQ10001          |  Q1,01 | P->P | RANGE      |
|   6 |       LOAD AS SELECT (HYBRID TSM/HWMB)| EMPLOYEE_REGISTRY |  Q1,01 | PCWP |            |
|   7 |        OPTIMIZER STATISTICS GATHERING |                   |  Q1,01 | PCWP |            |
|   8 |         SEQUENCE                      | EMP_ID_SEQ        |  Q1,01 | PCWC |            |
|   9 |          VIEW                         |                   |  Q1,01 | PCWP |            |
|  10 |           SORT ORDER BY               |                   |  Q1,01 | PCWP |            |
|  11 |            PX RECEIVE                 |                   |  Q1,01 | PCWP |            |
|  12 |             PX SEND RANGE             | :TQ10000          |  Q1,00 | P->P | RANGE      |
|  13 |              HASH JOIN                |                   |  Q1,00 | PCWP |            |
|  14 |               PX BLOCK ITERATOR       |                   |  Q1,00 | PCWC |            |
|  15 |                TABLE ACCESS FULL      | CANDIDATES        |  Q1,00 | PCWP |            |
|  16 |               TABLE ACCESS FULL       | DEPARTMENTS       |  Q1,00 | PCWP |            |
------------------------------------------------------------------------------------------------

如果你禁用并行DML,即使使用并行查询,也会像上面那样在协调器(P->S)处保持有序:

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name              |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT            |                   |        |      |            |
|   1 |  LOAD TABLE CONVENTIONAL    | EMPLOYEE_REGISTRY |        |      |            |
|   2 |   SEQUENCE                  | EMP_ID_SEQ        |        |      |            |
|   3 |    PX COORDINATOR           |                   |        |      |            |
|   4 |     PX SEND QC (ORDER)      | :TQ10001          |  Q1,01 | P->S | QC (ORDER) |
|   5 |      VIEW                   |                   |  Q1,01 | PCWP |            |
|   6 |       SORT ORDER BY         |                   |  Q1,01 | PCWP |            |
|   7 |        PX RECEIVE           |                   |  Q1,01 | PCWP |            |
|   8 |         PX SEND RANGE       | :TQ10000          |  Q1,00 | P->P | RANGE      |
|   9 |          HASH JOIN          |                   |  Q1,00 | PCWP |            |
|  10 |           TABLE ACCESS FULL | DEPARTMENTS       |  Q1,00 | PCWP |            |
|  11 |           PX BLOCK ITERATOR |                   |  Q1,00 | PCWC |            |
|  12 |            TABLE ACCESS FULL| CANDIDATES        |  Q1,00 | PCWP |            |
--------------------------------------------------------------------------------------
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章