如何加快以下sql查询?

时间:2011-12-19 19:30:11

标签: sql postgresql

  

可能重复:
  How can I speed up the following update query?

我想在运行postgresql 8.4的现代台式计算机上以可接受的时间(例如最多15分钟)运行以下查询:

UPDATE cap_options_rule_items
   SET cap_option_id = O.id
  FROM cap_options_rule_items I
  JOIN cap_options_rules R
    ON R.id = I.cap_options_rule_id
  JOIN cap_options O
    ON R.cap_engine_id = O.cap_engine_id
   AND O.code = I.cap_option_code;

我想知道我在查询中是否有明显的错误选择索引。

查询中的表具有以下记录数:

  • cap_options_rule_item:2208705
  • cap_options_rule:430268
  • cap_options:1628188

以下架构(包括索引)

-- Table: cap_options_rule_items
CREATE TABLE cap_options_rule_items  
(
  id serial NOT NULL,
  cap_options_rule_id integer,
  cap_option_code integer,
  "primary" boolean,
  cap_option_id integer,
  CONSTRAINT cap_options_rule_items_pkey PRIMARY KEY (id)
)
WITH (
 OIDS=FALSE
);

-- Index: index_cap_options_rule_items_on_cap_option_id
CREATE INDEX index_cap_options_rule_items_on_cap_option_id
    ON cap_options_rule_items
 USING btree (cap_option_code);

-- Index: index_cap_options_rule_items_on_cap_option_rule_id
CREATE INDEX index_cap_options_rule_items_on_cap_option_rule_id
    ON cap_options_rule_items
 USING btree (cap_options_rule_id);

-- Table: cap_options_rules
CREATE TABLE cap_options_rules
(
  id serial NOT NULL,
  rule_type character varying(255),
  cap_engine_id integer,
  CONSTRAINT cap_options_rules_pkey PRIMARY KEY (id)
) WITH ( OIDS=FALSE
 );

-- Index: index_cap_options_rules_on_cap_engine_id
CREATE INDEX index_cap_options_rules_on_cap_engine_id
    ON cap_options_rules
 USING btree (cap_engine_id);

-- Table: cap_options
CREATE TABLE cap_options
( id serial NOT NULL,
  description character varying(255),
  cap_engine_id integer,
  cap_option_category_id integer,
  basic_price numeric,
  vat numeric,
  default_option boolean,
  created_at timestamp without time zone,
  updated_at timestamp without time zone,
  code integer,
  CONSTRAINT cap_options_pkey PRIMARY KEY (id)
) WITH ( OIDS=FALSE
);


-- Index: index_code_and_cap_engine_id_on_cap_options
CREATE INDEX index_code_and_cap_engine_id_on_cap_options
 ON cap_options
  USING btree (code, cap_engine_id);

谢谢!

1 个答案:

答案 0 :(得分:3)

您的查询速度很慢,因为您要更新cap_options_rule_items中的所有行。

我认为你真的想要这样的东西:

UPDATE cap_options_rule_items I
   SET cap_option_id = O.id
  FROM cap_options_rules R
  join cap_options O on R.cap_engine_id = O.cap_engine_id
 WHERE I.cap_options_rule_id = R.id
   and I.cap_option_code = O.code;