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

时间:2015-03-10 20:06:06

标签: sql oracle plsql

很抱歉再次打扰,但我需要回答这个问题,因为我似乎无法想出一个问题。 这是上一篇文章:Is there any way I can speed up the following insert(s)?

请考虑以下事项:

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;
/

基于我在上一篇文章中得到的答案,我可以使用单个insert语句而不是一百万个(参见示例)轻松地在#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;

我在所有行上获得第3列的相同值,当我每次都想要不同的结果时(“随机”结果)。

再一次,感谢您抽出宝贵时间来看看这个!

2 个答案:

答案 0 :(得分:3)

将字符串放入子查询

的方法怎么样?
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语句返回超过12 mil的行,因此适当缩放。 我为LEVEl&lt; = 7和97k行运行它。在我的机器上花了3秒钟。

答案 1 :(得分:1)

这样的事情:

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;
/