插入超过 40k+ 行时如何提高性能
How to increase performance when inserting more than 40k+ rows
CREATE TABLE new_details_staging
(
e_id NUMBER(10),
e_name VARCHAR2(30),
portal_desc VARCHAR2(50),
risk_dec VARCHAR2(50),
CONSTRAINT pk_new_details_staging PRIMARY KEY (e_id)
);
INSERT INTO new_details_staging
VALUES (11, 'A', 'AA', 'High');
INSERT INTO new_details_staging
VALUES (22, 'B', 'BB', 'Low');
CREATE TABLE lookup_ref
(
ref_id NUMBER(10),
ref_typ VARCHAR2(30),
ref_typ_desc VARCHAR2(20),
CONSTRAINT pk_lookup_ref PRIMARY KEY (ref_id)
);
INSERT INTO lookup_ref
VALUES (181, 'portal', 'AA');
INSERT INTO lookup_ref
VALUES (182, 'portal', 'BB');
INSERT INTO lookup_ref
VALUES (183, 'risk', 'High');
INSERT INTO lookup_ref
VALUES (184, 'risk', 'Low');
CREATE TABLE new_details_main
(
e_id NUMBER(10),
e_name VARCHAR2(30),
portal NUMBER(20),
risk NUMBER(20),
CONSTRAINT pk_new_details_main PRIMARY KEY (e_id)
);
COMMIT;
我的尝试:
INSERT INTO new_details_main (e_id, e_name, portal,risk)
SELECT
n.e_id,
n.e_name,
(SELECT lr.ref_id
FROM lookup_ref lr
WHERE lr.ref_typ = 'portal'
AND lr.ref_typ_desc = n.portal_desc),
(SELECT lr.ref_id
FROM lookup_ref lr
WHERE lr.ref_typ = 'risk'
AND lr.ref_typ_desc = n.risk_dec)
FROM
new_details_staging n;
目前,我正在插入一些记录,它给出了准确的结果,但实际上,有 40k+ 条记录,所以我相信它也会带来性能问题。有什么方法可以更快地插入记录,因为我会为这个插入写一个程序?有没有其他我可以在过程中编写插入查询的地方?
在我的笔记本电脑上,我们可以轻松地扩展您的测试
SQL>
SQL> CREATE TABLE new_details_staging
2 (
3 e_id NUMBER(10),
4 e_name VARCHAR2(30),
5 portal_desc VARCHAR2(50),
6 risk_dec VARCHAR2(50),
7 CONSTRAINT pk_new_details_staging PRIMARY KEY (e_id)
8 );
Table created.
SQL>
SQL> INSERT INTO new_details_staging VALUES (11, 'A', 'AA', 'High');
1 row created.
SQL> INSERT INTO new_details_staging VALUES (22, 'B', 'BB', 'Low');
1 row created.
SQL>
SQL> insert into new_details_staging
2 select e_id*500000+rownum, e_name, portal_desc, risk_dec
3 from new_details_staging,
4 ( select 1 from dual connect by level <= 400000 );
800000 rows created.
SQL>
SQL> CREATE TABLE lookup_ref
2 (
3 ref_id NUMBER(10),
4 ref_typ VARCHAR2(30),
5 ref_typ_desc VARCHAR2(20),
6 CONSTRAINT pk_lookup_ref PRIMARY KEY (ref_id)
7 );
Table created.
SQL>
SQL> INSERT INTO lookup_ref VALUES (181, 'portal', 'AA');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (182, 'portal', 'BB');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (183, 'risk', 'High');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (184, 'risk', 'Low');
1 row created.
SQL>
SQL> CREATE TABLE new_details_main
2 (
3 e_id NUMBER(10),
4 e_name VARCHAR2(30),
5 portal NUMBER(20),
6 risk NUMBER(20),
7 CONSTRAINT pk_new_details_main PRIMARY KEY (e_id)
8 );
Table created.
SQL>
SQL> set timing on
SQL> INSERT INTO new_details_main (e_id, e_name, portal,risk)
2 SELECT
3 n.e_id,
4 n.e_name,
5 (SELECT lr.ref_id
6 FROM lookup_ref lr
7 WHERE lr.ref_typ = 'portal'
8 AND lr.ref_typ_desc = n.portal_desc),
9 (SELECT lr.ref_id
10 FROM lookup_ref lr
11 WHERE lr.ref_typ = 'risk'
12 AND lr.ref_typ_desc = n.risk_dec)
13 FROM
14 new_details_staging n;
800002 rows created.
Elapsed: 00:00:02.97
SQL>
SQL>
所以 800,000 行大约需要 3 秒。我想你会没事的:-)
如果查找始终为真并保留密钥,则转换为联接可能会带来一些好处,例如
SQL> set timing on
SQL> INSERT INTO new_details_main (e_id, e_name, portal,risk)
2 SELECT
3 n.e_id,
4 n.e_name,
5 lr.ref_id,
6 lr1.ref_id
7 FROM
8 new_details_staging n,
9 lookup_ref lr,
10 lookup_ref lr1
11 where lr.ref_typ = 'portal'
12 AND lr.ref_typ_desc = n.portal_desc
13 and lr1.ref_typ = 'risk'
14 AND lr1.ref_typ_desc = n.risk_dec ;
800002 rows created.
Elapsed: 00:00:02.64
CREATE TABLE new_details_staging
(
e_id NUMBER(10),
e_name VARCHAR2(30),
portal_desc VARCHAR2(50),
risk_dec VARCHAR2(50),
CONSTRAINT pk_new_details_staging PRIMARY KEY (e_id)
);
INSERT INTO new_details_staging
VALUES (11, 'A', 'AA', 'High');
INSERT INTO new_details_staging
VALUES (22, 'B', 'BB', 'Low');
CREATE TABLE lookup_ref
(
ref_id NUMBER(10),
ref_typ VARCHAR2(30),
ref_typ_desc VARCHAR2(20),
CONSTRAINT pk_lookup_ref PRIMARY KEY (ref_id)
);
INSERT INTO lookup_ref
VALUES (181, 'portal', 'AA');
INSERT INTO lookup_ref
VALUES (182, 'portal', 'BB');
INSERT INTO lookup_ref
VALUES (183, 'risk', 'High');
INSERT INTO lookup_ref
VALUES (184, 'risk', 'Low');
CREATE TABLE new_details_main
(
e_id NUMBER(10),
e_name VARCHAR2(30),
portal NUMBER(20),
risk NUMBER(20),
CONSTRAINT pk_new_details_main PRIMARY KEY (e_id)
);
COMMIT;
我的尝试:
INSERT INTO new_details_main (e_id, e_name, portal,risk)
SELECT
n.e_id,
n.e_name,
(SELECT lr.ref_id
FROM lookup_ref lr
WHERE lr.ref_typ = 'portal'
AND lr.ref_typ_desc = n.portal_desc),
(SELECT lr.ref_id
FROM lookup_ref lr
WHERE lr.ref_typ = 'risk'
AND lr.ref_typ_desc = n.risk_dec)
FROM
new_details_staging n;
目前,我正在插入一些记录,它给出了准确的结果,但实际上,有 40k+ 条记录,所以我相信它也会带来性能问题。有什么方法可以更快地插入记录,因为我会为这个插入写一个程序?有没有其他我可以在过程中编写插入查询的地方?
在我的笔记本电脑上,我们可以轻松地扩展您的测试
SQL>
SQL> CREATE TABLE new_details_staging
2 (
3 e_id NUMBER(10),
4 e_name VARCHAR2(30),
5 portal_desc VARCHAR2(50),
6 risk_dec VARCHAR2(50),
7 CONSTRAINT pk_new_details_staging PRIMARY KEY (e_id)
8 );
Table created.
SQL>
SQL> INSERT INTO new_details_staging VALUES (11, 'A', 'AA', 'High');
1 row created.
SQL> INSERT INTO new_details_staging VALUES (22, 'B', 'BB', 'Low');
1 row created.
SQL>
SQL> insert into new_details_staging
2 select e_id*500000+rownum, e_name, portal_desc, risk_dec
3 from new_details_staging,
4 ( select 1 from dual connect by level <= 400000 );
800000 rows created.
SQL>
SQL> CREATE TABLE lookup_ref
2 (
3 ref_id NUMBER(10),
4 ref_typ VARCHAR2(30),
5 ref_typ_desc VARCHAR2(20),
6 CONSTRAINT pk_lookup_ref PRIMARY KEY (ref_id)
7 );
Table created.
SQL>
SQL> INSERT INTO lookup_ref VALUES (181, 'portal', 'AA');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (182, 'portal', 'BB');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (183, 'risk', 'High');
1 row created.
SQL> INSERT INTO lookup_ref VALUES (184, 'risk', 'Low');
1 row created.
SQL>
SQL> CREATE TABLE new_details_main
2 (
3 e_id NUMBER(10),
4 e_name VARCHAR2(30),
5 portal NUMBER(20),
6 risk NUMBER(20),
7 CONSTRAINT pk_new_details_main PRIMARY KEY (e_id)
8 );
Table created.
SQL>
SQL> set timing on
SQL> INSERT INTO new_details_main (e_id, e_name, portal,risk)
2 SELECT
3 n.e_id,
4 n.e_name,
5 (SELECT lr.ref_id
6 FROM lookup_ref lr
7 WHERE lr.ref_typ = 'portal'
8 AND lr.ref_typ_desc = n.portal_desc),
9 (SELECT lr.ref_id
10 FROM lookup_ref lr
11 WHERE lr.ref_typ = 'risk'
12 AND lr.ref_typ_desc = n.risk_dec)
13 FROM
14 new_details_staging n;
800002 rows created.
Elapsed: 00:00:02.97
SQL>
SQL>
所以 800,000 行大约需要 3 秒。我想你会没事的:-)
如果查找始终为真并保留密钥,则转换为联接可能会带来一些好处,例如
SQL> set timing on
SQL> INSERT INTO new_details_main (e_id, e_name, portal,risk)
2 SELECT
3 n.e_id,
4 n.e_name,
5 lr.ref_id,
6 lr1.ref_id
7 FROM
8 new_details_staging n,
9 lookup_ref lr,
10 lookup_ref lr1
11 where lr.ref_typ = 'portal'
12 AND lr.ref_typ_desc = n.portal_desc
13 and lr1.ref_typ = 'risk'
14 AND lr1.ref_typ_desc = n.risk_dec ;
800002 rows created.
Elapsed: 00:00:02.64