今天早些时候跟进:有什么方法可以加快以下插入速度吗?

Follow up on earlier today: Is there any way I can speed up the following insert(s)?

抱歉再次打扰,但我需要这个问题的答案,因为我自己似乎想不出一个答案。 这是之前的post:.

考虑以下几点:

CREATE TABLE myTable
        (
        random_value1 NUMBER,
        random_value2 NUMBER,
        random_string VARCHAR2(5)
        );

DECLARE
  TYPE arrayType IS VARRAY(5) OF VARCHAR2(5);
  v_my_array arrayType := arrayType('foo', 'bar', 'baz', 'qux', 'quux');
  max NUMBER := 1000000;
BEGIN
  FOR j IN 1..max
  LOOP
    INSERT INTO myTable VALUES(DBMS_RANDOM.VALUE(1, 500), 
      DBMS_RANDOM.VALUE(1, 500), v_my_array(DBMS_RANDOM.VALUE(1, 5)));
  END LOOP;
END;
/

根据我在上一个 post 中得到的答案,我可以使用单个插入语句而不是一百万个(参见示例)轻松地在列 #1 和 #2 上插入随机值。现在我的问题是如何从给定字符串列表中插入一个随机字符串并避免使用循环,当然如果可能的话。 如果我尝试这样的事情:

INSERT INTO myTable
  SELECT
    DBMS_RANDOM.VALUE(1, 500),
    DBMS_RANDOM.VALUE(1, 500),
    v_my_array(DBMS_RANDOM.VALUE(1, 5))
  FROM DUAL
  CONNECT BY
    LEVEL <= 1000000;

当我每次都想要不同的结果("random" 个结果)时,我在所有行的第 3 列得到相同的值。

再次感谢您抽出时间查看本文!

像这样:

DECLARE
  TYPE arrayType IS VARRAY(5) OF VARCHAR2(5);
  v_my_array arrayType := arrayType('foo', 'bar', 'baz', 'qux', 'quux');
  max NUMBER := 1000000;
  TYPE t_data IS TABLE OF myTable%ROWTYPE INDEX BY PLS_INTEGER;
  v_data t_data;
  v_row  myTable%ROWTYPE;
BEGIN
  FOR i IN 1..10
  LOOP
     FOR j IN 1..100000
     LOOP
       v_row.random_value1 := DBMS_RANDOM.VALUE(1, 500);
       v_row.random_value2 := DBMS_RANDOM.VALUE(1, 500);
       v_row.random_string := v_my_array(DBMS_RANDOM.VALUE(1, 5));
       v_data(j) := v_row;
     END LOOP;
     FORALL k IN INDICIES OF v_data
       INSERT INTO myTable VALUES v_Data(k);
  END LOOP;
END;
/

这种将字符串放入子查询的方法怎么样

INSERT INTO myTable

SELECT
   DBMS_RANDOM.VALUE(1, 500),
   DBMS_RANDOM.VALUE(1, 500),
   myvarchar.a
FROM 
(select a from
(
SELECT 'foo' a from dual
union 
select 'bar' a from dual
union 
select 'baz' a from dual
union 
select 'qux' a from dual
union 
select 'quux' a from dual
 )
ORDER BY 
DBMS_RANDOM.RANDOM) myvarchar
CONNECT BY
LEVEL <= 10;
 /

此 select 语句 returns 超过 1200 万行,因此请适当缩放。 我 运行 它用于 LEVEl<=7 和 97k 行。在我的机器上花了 3 秒。