[pgsql-jp: 26449] Re: 大量データの更新

sugita @ sra.co.jp sugita @ sra.co.jp
2002年 6月 19日 (水) 12:13:33 JST


  杉田です。

From: "Hashimoto, Masaru" <hashimoto-m @ comtecc.net>
Subject: [pgsql-jp: 26423] Re: 大量データの更新
Date: Tue, 18 Jun 2002 14:54:23 +0900

;;; それで、いろいろ調査をしてみた結果、
;;; UPDATEの場合もINSERTの場合もINDEXが使用されていないようです。
;;; user_idの方はTB作成時にidをPRIMARY KEYにしていしてます。
;;; また、work_user_tbの方はidでINDEXを作成しています。
;;; 
;;; これをIndex Scanにすることができれば、
;;; 少しは早くなるような気がするのですが・・・
;;; ちなみに、それぞれをSQL文をSELECTに置き換えても同じ結果でした。
;;; 
;;; =UPDATEの場合のEXPLAIN=
;;; Nested Loop  (cost=0.00..472022230.82 rows=2634084249 width=1784)
;;;   ->  Seq Scan on user_tb  (cost=0.00..359796.33 rows=3629 width=957)
;;;   ->  Seq Scan on work_user_tb  (cost=0.00..122708.21 rows=725821 width=827)

  このクエリーの explain でよいでしょうか?

    UPDATE user_tb SET user_tb.name = work_user_tb.name
    FROM work_user_tb
    WHERE user_tb.id = work_user_tb.id;

  PostgreSQL 7.2.1 で、以下のように、user_tb に 3629 レコードをキー 0〜3628、
work_user_tb に 725821 レコードをキー0〜725820 入れてみました。

    =# create table class1 (i integer primary key, n text);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'class1_pkey' for ta
    CREATE
    =# create table class2 (i integer primary key, n text);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'class2_pkey' for ta
    CREATE
    =# insert into class1 select gennum(3629);	    -- 0〜3628 を返すユーザ定義関数です
    INSERT 0 3629
    =# insert into class2 select gennum(725821);    -- 同上。
    INSERT 0 725821
    =# analyze;
    ANALYZE
    =# \!cat a.sql
    explain update class1 set n = class2.n
	from class2
	where class1.i = class2.i
	;
    =# \i a.sql
    psql:a.sql:4: NOTICE:  QUERY PLAN:

    Nested Loop  (cost=0.00..7553.20 rows=3700 width=46)
      ->  Seq Scan on class1  (cost=0.00..57.00 rows=3700 width=10)
      ->  Index Scan using class2_pkey on class2  (cost=0.00..2.01 rows=1 width=36)

    EXPLAIN
    =# 

  class2 の方にはインデックスが使われました。データの分布を以下のように分散さ
せた場合にもインデックスが使われています。

    =# insert into class1 select gennum(3628, 0, 200);
    INSERT 0 3628
    =# insert into class2 select gennum(3628, 0, 200);
    ...
    =# insert into class2 select gennum(3628, 67, 200);
    =# insert into class2 select gennum(3849, 725600);
    INSERT 0 3849
    =# select count(*) from class2;
     count  
    --------
     725821
    (1 row)

    =# analyze;
    =# \i a.sql
    psql:a.sql:4: NOTICE:  QUERY PLAN:

    Nested Loop  (cost=0.00..18645.41 rows=3700 width=46)
      ->  Seq Scan on class1  (cost=0.00..57.00 rows=3700 width=10)
      ->  Index Scan using class2_pkey on class2  (cost=0.00..5.01 rows=1 width=36)

    EXPLAIN
    =# 


Kenji Sugita
sugita @ sra.co.jp



pgsql-jp メーリングリストの案内