Java 在N:M表中插入PostgreSQL数据的最快方法是什么?

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

我有一个应用程序需要在数据库中插入很多行,但目前插入速度太慢,我想知道什么是将插入速度提高到最大的最佳技术

情况是在每次插入中,我需要发现令牌的id,为此,我将SELECT放在插入中

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;