Java 在N:M表中插入PostgreSQL数据的最快方法是什么?
我有一个应用程序需要在数据库中插入很多行,但目前插入速度太慢,我想知道什么是将插入速度提高到最大的最佳技术 情况是在每次插入中,我需要发现令牌的id,为此,我将SELECT放在插入中 在Java 在N:M表中插入PostgreSQL数据的最快方法是什么?,java,sql,postgresql,Java,Sql,Postgresql,我有一个应用程序需要在数据库中插入很多行,但目前插入速度太慢,我想知道什么是将插入速度提高到最大的最佳技术 情况是在每次插入中,我需要发现令牌的id,为此,我将SELECT放在插入中 在textBlockHasToken表(包括SQL和Java)中,哪一个是加速最大插入的最佳解决方案 编辑:目前可以使用,但我有大量的数据流。一些数字,令牌表中有100.000个不同的行,textBlockHasToken中有200万行 我有三个表和两个insert SQL: -- Text blocks of t
textBlockHasToken
表(包括SQL和Java)中,哪一个是加速最大插入的最佳解决方案
编辑:目前可以使用,但我有大量的数据流。一些数字,令牌表中有100.000个不同的行,textBlockHasToken中有200万行
我有三个表和两个insert SQL:
-- Text blocks of the pages
CREATE TABLE textBlock(
id INTEGER PRIMARY KEY,
pageId INTEGER REFERENCES page,
text VARCHAR NOT NULL,
position INTEGER NOT NULL
);
-- Tokens in the text blocks
CREATE TABLE token(
id INTEGER PRIMARY KEY,
text VARCHAR NOT NULL,
charType VARCHAR NOT NULL,
grammar VARCHAR NOT NULL,
category VARCHAR[] NOT NULL,
stopWord BOOLEAN NOT NULL DEFAULT false,
UNIQUE(text)
);
-- N:N relationship between textblock and token
CREATE TABLE textBlockHasToken(
textBlockId INTEGER REFERENCES textBlock NOT NULL,
tokenId INTEGER REFERENCES token NOT NULL,
sentence INTEGER NOT NULL,
position INTEGER NOT NULL
);
-- Insert the token
INSERT INTO token(id,text,charType,grammar,category)
VALUES(nextval('tokenIdSqc'),?,?,?,?);
-- Insert in relationship in N:M
INSERT INTO textBlockHasToken(textblockId,tokenId,sentence,position)
VALUES(?,(SELECT id FROM token WHERE text = ?),?,?);
最好的办法是确保所有WHERE变量都有与其关联的索引。它们是为主键自动创建的;确保外键列也有索引
另一个考虑因素是批处理请求。不要为每次插入做网络往返;将它们批处理成块并提交每个块。这将意味着更少的网络往返和可管理的事务日志。最好的办法是确保所有WHERE变量都有与其相关联的索引。它们是为主键自动创建的;确保外键列也有索引
另一个考虑因素是批处理请求。不要为每次插入做网络往返;将它们批处理成块并提交每个块。这将意味着更少的网络往返和可管理的事务日志。我完全同意duffymo的观点,但我还要补充一点,这是导入数据的最佳方式
当然,这样做并不总是可行的,尤其是在代码内部。这就是为什么我也同意duffymo的观点,如果你需要在一台单独的机器上编写代码,就按照duffymo说的去做。我完全同意duffymo的观点,但我还要补充一点,这是导入数据的一种方式
当然,这样做并不总是可行的,尤其是在代码内部。这就是为什么我也同意duffymo的观点,如果你需要在一台单独的机器上编写代码,按照duffymo说的去做。duffymo已经提到了批量更新。我想补充一句:
- 您是否对一笔交易的不同规模进行过实验/测量
- 您是否已经使用和重用准备好的语句
- 您是否尝试过/测量过“INSERT-INTO-token…RETURNING-id”并将其直接输入到第二条INSERT语句中
但在不了解任何现有代码的情况下,这完全是猜测。duffymo已经提到了批量更新。我想补充一句:
- 您是否对一笔交易的不同规模进行过实验/测量
- 您是否已经使用和重用准备好的语句
- 您是否尝试过/测量过“INSERT-INTO-token…RETURNING-id”并将其直接输入到第二条INSERT语句中
- 不要将保留字用作标识符(文本、日期)
- (请不要使用MixedCaseIdentifiers)
- 您的表定义不起作用。下面的那个确实有效
- 不要将保留字用作标识符(文本、日期)
- (请不要使用MixedCaseIdentifiers)
- 您的表定义不起作用。下面的那个确实有效
这是一个很好的建议,远离标识符。然而,
text
在PostgreSQL和所有SQL标准中都是非保留的。(我仍然不会使用它来避免混淆错误,因为它也是数据类型的名称。)不管怎样,它不是很具有描述性。一个更好的名字应该更能自我记录。最好不要使用标识符。然而,text
在PostgreSQL和所有SQL标准中都是非保留的。(我仍然不会使用它来避免混淆错误,因为它也是数据类型的名称。)不管怎样,它不是很具有描述性。一个更好的名字应该是更多的自我记录
-- Text blocks of the pages
DROP TABLE tmp.textblock CASCADE;
CREATE TABLE tmp.textblock
( id INTEGER PRIMARY KEY
, pageid INTEGER -- REFERENCES page
, ztext VARCHAR NOT NULL
, position INTEGER NOT NULL
);
-- Tokens in the text blocks
DROP TABLE tmp.token CASCADE;
DROP SEQUENCE tmp.tokenidsqc;
CREATE SEQUENCE tmp.tokenidsqc;
CREATE TABLE tmp.token
( id INTEGER PRIMARY KEY DEFAULT nextval('tmp.tokenidsqc')
, ztext VARCHAR NOT NULL
, chartype VARCHAR NOT NULL
, grammar VARCHAR NOT NULL
, category VARCHAR NOT NULL
, stopword BOOLEAN NOT NULL DEFAULT false
, UNIQUE(ztext)
);
-- N:N relationship between textblock and token
DROP TABLE tmp.textblockhastoken CASCADE;
CREATE TABLE tmp.textblockhastoken
( textblockid INTEGER NOT NULL REFERENCES tmp.textblock(id)
, tokenid INTEGER NOT NULL REFERENCES tmp.token(id)
, sentence INTEGER NOT NULL
, position INTEGER NOT NULL
);
-- Insert the token
INSERT INTO tmp.token(ztext,chartype,grammar,category)
VALUES('foo' , 'T' , 'a', 'a' ), ('bar' , 'T' , 'a', 'a' );
SELECT * FROM tmp.token;