【问题标题】:Which is the fastest way to insert data in PostgreSQL in a N:M table?在 N:M 表中的 PostgreSQL 中插入数据的最快方法是什么?
【发布时间】:2011-11-01 06:57:09
【问题描述】:

我有一个应用程序需要在数据库中插入很多行,但是目前插入速度太慢,我想知道什么是最好的技术来加快插入速度。

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

在包括 SQL 和 Java 在内的textBlockHasToken 表中最大程度地加快插入速度的最佳解决方案是什么?

编辑:目前可以使用,但我的数据流很大。一些数字,令牌表中有 100.000 行不同的行,textBlockHasToken 中有 200 万行。

我有这三个表和两个插入 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 = ?),?,?);

【问题讨论】:

标签: java sql postgresql


【解决方案1】:

您能做的最好的事情是确保所有 WHERE 变量都有与之关联的索引。它们是为主键自动创建的;确保外键列也有索引。

另一个考虑因素是批处理请求。不要为每个 INSERT 做一次网络往返;将它们分批处理并提交每个块。这将意味着更少的网络往返和可管理的事务日志。

【讨论】:

    【解决方案2】:
    • 不要使用保留字作为标识符(文本、日期)
    • (请不要使用 MixedCaseIdentifiers)
    • 您的表定义不起作用。下面的方法确实有效。

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

    【讨论】:

    • 建议远离reserved word 获取标识符。但是,text 在 PostgreSQL 和每个 SQL 标准中都是非保留的。 (我仍然不会使用它来避免混淆错误,因为它也是数据类型的名称。)
    • 无论如何,它不是很具有描述性。一个更好的名字应该更能自我记录。
    【解决方案3】:

    我完全同意 duffymo,但我还要补充一点,Postgres's COPY feature 是导入数据的品味方式..

    当然,这样做并不总是可行的,尤其是在代码中。这就是为什么我也同意 duffymo 的原因,如果您需要从单独机器上的代码执行此操作,请按照 duffymo 所说的进行。

    【讨论】:

      【解决方案4】:

      duffymo 已经提到了批量更新。只是为了确保我会添加:

      • 您是否对一笔交易的不同大小进行了实验/测量?
      • 您是否已经使用和重用预准备语句?
      • 您是否对“INSERT INTO token ... RETURNING id”进行了实验/测量,并将其直接输入到第二个插入语句中?

      但在对现有代码一无所知的情况下,这完全是猜测。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-23
        相关资源
        最近更新 更多