【问题标题】:PL SQL Insert indexPL SQL 插入索引
【发布时间】:2026-01-17 15:55:02
【问题描述】:

我需要向表中插入 500.000 条记录,因此该过程需要一段时间。我阅读了提高查询速度的索引,但接下来的问题是:我应该在哪个参数上设置索引以使 INSERT 更快? (身份证?)。 谢谢。

编辑

CREATE OR REPLACE PROCEDURE addNewUser(
                            firstName IN VARCHAR2,
                            lastName IN VARCHAR2,
                            email IN VARCHAR2,
                            username IN VARCHAR2,
                            password IN VARCHAR2,
                            job IN VARCHAR2) AS
  v_usersCount NUMBER := 0;
  v_userID NUMBER := 0;

BEGIN 
  SELECT COUNT(*) INTO v_usersCount
  FROM Users;

  v_userID := v_usersCount + 1;

  INSERT INTO Users VALUES(v_userID,firstName,lastName,email,username,password,job);
END addNewUser;

数据是这样添加的:

FOR i IN 1..50000
LOOP
    addNewTask('Task 1', 'Just Starter', 'High', 1, 'This is a description task.', 'Task Comment', '20-08-2015', 1);
END LOOP;

【问题讨论】:

  • 您使用索引来更快地访问数据,而不是加快插入速度。索引不会使INSERTs 更快,但它们可以使它们变慢,因为索引需要为每个添加的行更新。
  • 好吧,我错了。感谢您的答复。你知道为什么插入 1000 行需要大约 13 秒(我的笔记本电脑的硬件会影响这个查询吗?)
  • 服务器的硬件、内存、资源限制和设置都会有影响。桌子上有触发器吗?您是一次插入一行(逐行,有时称为“缓慢”)还是分批插入?你在插入之间提交吗?您是否在插入之间进行任何查询或 PL/SQL 工作? 500,000 行的数据来自哪里?
  • 这与 PL/SQL 有什么关系?您不是在游标中进行一些缓慢的逐行处理,对吗?
  • 由于context switching,将每个插入包装到过程调用中会导致性能问题。您可以简单地使用 SEQUENCE 来填充 id 列。

标签: oracle indexing plsql records


【解决方案1】:

您正在为每次插入进行查询,这使得它变慢了。

尝试计算存储之外的 ID 并将其传递给过程,这样您就不必每次都在过程中查询它。

【讨论】:

    【解决方案2】:

    SELECT COUNT(*)... 是您在任何程序中可以做的最慢的事情之一。这需要读取表中的每一行 - 因此,如果您第一次插入 1000 行,它会读取零行(快速),下一次读取 1 行(快速),下一次读取 2 行......最终你已经执行了 1000查询并读取 499500 行(0 到 999 的总和)。

    在这种情况下,您应该使用 SEQUENCE 来生成不重复的数字。我会将您的代码重写为:

    CREATE SEQUENCE VALUE_SEQ;  -- just take defaults for all parameters
    
    CREATE OR REPLACE PROCEDURE addNewUser(
                                firstName IN VARCHAR2,
                                lastName IN VARCHAR2,
                                email IN VARCHAR2,
                                username IN VARCHAR2,
                                password IN VARCHAR2,
                                job IN VARCHAR2) AS
    BEGIN 
      INSERT INTO Users
        VALUES(VALUE_SEQ.NEXTVAL, firstName,lastName,
               email,username,password,job);
    END addNewUser;
    

    【讨论】: