0

現在、データベースを Microsoft SQL Server から PostgreSQL 9.1 に移行しています。ストアの概要を計算するための簡単なクエリがあります。

SELECT DISTINCT  p.part_name_id,

(SELECT     SUM(p1.quantity) 
FROM          parts.spareparts p1
WHERE      p1.part_name_id = p.part_name_id) AS AllQuantity, 

(SELECT     SUM(p2.price * p2.quantity) 
FROM          parts.spareparts p2 
WHERE      p2.part_name_id = p.part_name_id) AS AllPrice 


FROM parts.spareparts p

MSSQL では 1 秒未満で非常に高速に動作し、sparepartsテーブルには約 150 000 のレコードがあります。

PostgreSQL では、結果を待たずに 200,000 ミリ秒待ちました。

どこが間違っていたのですか?

PS: テーブル定義:

-- Table: parts.spareparts

-- DROP TABLE parts.spareparts;

CREATE TABLE parts.spareparts
(
  id serial NOT NULL,
  big_id bigint NOT NULL,
  part_unique integer NOT NULL,
  store_address integer,
  brand_id integer,
  model_id integer,
  category_id integer,
  part_name_id integer,
  price money,
  quantity integer,
  description character varying(250),
  private_info character varying(600),
  manager_id integer,
  company_id integer,
  part_type smallint,
  box_number integer,
  com_person character varying(200),
  com_phone character varying(200),
  vendor_id integer,
  is_publish boolean DEFAULT true,
  is_comission boolean DEFAULT false,
  is_new boolean DEFAULT false,
  is_warning boolean DEFAULT false,
  catalog_no character varying(200),
  disc_id integer,
  is_set boolean,
  w_height numeric(3,2),
  w_width numeric(3,2),
  w_diam numeric(3,2),
  w_type integer,
  page_url character varying(150),
  last_edit_manager_id integer,
  CONSTRAINT spareparts_pk PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE parts.spareparts
  OWNER TO asap;

-- Index: parts.sparepart_part_unique_idx

-- DROP INDEX parts.sparepart_part_unique_idx;

CREATE INDEX sparepart_part_unique_idx
  ON parts.spareparts
  USING btree
  (part_unique, company_id);

-- Index: parts.spareparts_4param_idx

-- DROP INDEX parts.spareparts_4param_idx;

CREATE INDEX spareparts_4param_idx
  ON parts.spareparts
  USING btree
  (brand_id, model_id, category_id, part_name_id);

-- Index: parts.spareparts_bigid_idx

-- DROP INDEX parts.spareparts_bigid_idx;

CREATE INDEX spareparts_bigid_idx
  ON parts.spareparts
  USING btree
  (big_id);

-- Index: parts.spareparts_brand_id_part_id_quantity_idx

-- DROP INDEX parts.spareparts_brand_id_part_id_quantity_idx;

CREATE INDEX spareparts_brand_id_part_id_quantity_idx
  ON parts.spareparts
  USING btree
  (brand_id, part_name_id, quantity);

-- Index: parts.spareparts_brand_id_quantity_idx

-- DROP INDEX parts.spareparts_brand_id_quantity_idx;

CREATE INDEX spareparts_brand_id_quantity_idx
  ON parts.spareparts
  USING btree
  (brand_id, quantity);

-- Index: parts.spareparts_company_id_part_unique_idx

-- DROP INDEX parts.spareparts_company_id_part_unique_idx;

CREATE INDEX spareparts_company_id_part_unique_idx
  ON parts.spareparts
  USING btree
  (company_id, part_unique);

-- Index: parts.spareparts_model_id_company_id

-- DROP INDEX parts.spareparts_model_id_company_id;

CREATE INDEX spareparts_model_id_company_id
  ON parts.spareparts
  USING btree
  (model_id, company_id);
COMMENT ON INDEX parts.spareparts_model_id_company_id
  IS 'Для frmFilter';

-- Index: parts.spareparts_url_idx

-- DROP INDEX parts.spareparts_url_idx;

CREATE INDEX spareparts_url_idx
  ON parts.spareparts
  USING btree
  (page_url COLLATE pg_catalog."default");


-- Trigger: spareparts_delete_trigger on parts.spareparts

-- DROP TRIGGER spareparts_delete_trigger ON parts.spareparts;

CREATE TRIGGER spareparts_delete_trigger
  AFTER DELETE
  ON parts.spareparts
  FOR EACH ROW
  EXECUTE PROCEDURE parts.spareparts_delete_fn();

-- Trigger: spareparts_update_trigger on parts.spareparts

-- DROP TRIGGER spareparts_update_trigger ON parts.spareparts;

CREATE TRIGGER spareparts_update_trigger
  AFTER INSERT OR UPDATE
  ON parts.spareparts
  FOR EACH ROW
  EXECUTE PROCEDURE parts.spareparts_update_fn();
4

2 に答える 2

1

サブクエリは実際には必要ないと思います。簡単に書くことができます:

SELECT part_name_id,
       SUM(quantity) AS AllQuantity,
       SUM(price * quantity) AS AllPrice
  FROM parts.spare_parts
 GROUP
    BY part_name_id
;

これははるかに効率的です。

于 2013-07-27T19:37:53.960 に答える
1

ネストされた選択を必要とせずにクエリを書き直すことができると思います:

SELECT p.part_name_id,
       SUM(p.quantity) AS AllQuantity, 
       SUM(p.price * p.quantity) AS AllPrice 
FROM parts.spareparts p
group by p.part_name_id
于 2013-07-27T19:38:01.553 に答える