为什么添加一个smallint列导致查询速度减慢60倍?

时间:2016-01-07 18:22:02

标签: sql postgresql

在这里,我看起来像是一个例程表和一个表创建脚本,我已放入/tmp/try.sql。我在OSX 10.10.2下运行postgres。

这是表格:

cow_dev=# \d carc
                                Table "public.carc"
    Column     |     Type     |                         Modifiers
---------------+--------------+---------------------------------------------------   ---------
 internal_id   | integer      | not null default nextval('carc_internal_id_seq'::regclass)
 acct_nbr      | character(6) |
 birth_date    | date         |
 anm_key       | integer      |
 slghtr_dt     | date         |
 sire_assoc_id | integer      |
 sire_reg      | text         |
 dam_assoc_id  | integer      |
 dam_reg       | text         |
 sex           | text         |
 carc_kphf_pct | real         |
 carc_wt       | integer      |
 marbling      | integer      |
 ribeye_area   | real         |
 usda_qlty_grd | smallint     |
 act_fat_thick | real         |
 carcass_group | text         |
 maturity      | integer      |
Indexes:
    "idx_a649568319866892fcdd3742289e8294" PRIMARY KEY, btree (internal_id)
    "idx_d4659e9f750ff68c75e11e89a950e386" btree (anm_key)
    "idx_d57025002b9ce54cf590b76e87c10cac" btree (acct_nbr)
Foreign-key constraints:
    "carc_acct_nbr__acct_acct_nbr_fk" FOREIGN KEY (acct_nbr) REFERENCES acct(acct_nbr)
    "carc_anm_key__anm_anm_key_fk" FOREIGN KEY (anm_key) REFERENCES anm(anm_key)

这是脚本:

create temp table carc_out as
     with assoc_map as 
     (select
         a.assoc_id,
         c.code_3 || a.brd_cd_id mb_name
      from
         assoc a
         join country_code c on c.code_2 = a.country_code_2)
     select
        c.internal_id,
        n.mb_assoc_reg anm_nbr,
        c.act_fat_thick,
        c.carc_kphf_pct,
        c.carcass_group,
        c.carc_wt,
        null::float carc_yld,
        c.marbling,
        c.maturity,
        c.ribeye_area,
        to_char(c.slghtr_dt, 'mmddyyyy') slghtr_dt,
        c.usda_qlty_grd
from
        carc c
        left join z2_raa_numbers n using (anm_key)
        left join assoc_map da on da.assoc_id = coalesce(c.dam_assoc_id, 1) 
        left join assoc_map sa on sa.assoc_id = coalesce(c.sire_assoc_id, 1);
drop table carc_out;

以下是运行两次的结果,第一次是c.usda_qlty_grd未包含在查询中,第二次包含它。

> time psql -U cow_peer -d cow_dev -c '\i /tmp/try.sql'
SELECT 25332
DROP TABLE

real    0m3.041s
user    0m0.004s
sys     0m0.004s
10:57:46 521 0 tom@angus-2 ~
> time psql -U cow_peer -d cow_dev -c '\i /tmp/try.sql'
SELECT 25332
DROP TABLE

real    3m1.958s
user    0m0.004s
sys     0m0.004s

如您所见,一次需要3秒,另一次需要3分钟。这是可重复的,并且至少在某种程度上与您添加到查询中的其他列无关。有趣的是,用户和系统时间似乎并没有改变。我很困惑。

我提出的任何执行计划相同的声明都是错误的。但是,有很多相似之处。

这没有额外的专栏:

                                     QUERY PLAN
---------------------------------------------------------------------------------------------
 Hash Left Join  (cost=1220.51..122913.55 rows=25332 width=54)
   Hash Cond: (COALESCE(c.sire_assoc_id, 1) = sa.assoc_id)
   CTE assoc_map
 ->  Hash Join  (cost=7.54..10.16 rows=52 width=11)
       Hash Cond: (a.country_code_2 = c_1.code_2)
           ->  Seq Scan on assoc a  (cost=0.00..1.52 rows=52 width=10)
           ->  Hash  (cost=4.46..4.46 rows=246 width=7)
                 ->  Seq Scan on country_code c_1  (cost=0.00..4.46 rows=246 width=7)
   ->  Hash Left Join  (cost=1208.66..122614.19 rows=25332 width=58)
         Hash Cond: (COALESCE(c.dam_assoc_id, 1) = da.assoc_id)
         ->  Hash Right Join  (cost=1206.97..122451.64 rows=25332 width=62)
               Hash Cond: (n.anm_key = c.anm_key)
              ->  Seq Scan on z2_raa_numbers n  (cost=0.00..61034.69 rows=3330869 width=19)
               ->  Hash  (cost=642.32..642.32 rows=25332 width=51)
                 ->  Seq Scan on carc c  (cost=0.00..642.32 rows=25332 width=51)
     ->  Hash  (cost=1.04..1.04 rows=52 width=4)
           ->  CTE Scan on assoc_map da  (cost=0.00..1.04 rows=52 width=4)
   ->  Hash  (cost=1.04..1.04 rows=52 width=4)
         ->  CTE Scan on assoc_map sa  (cost=0.00..1.04 rows=52 width=4)

这个包含附加列:

                                        QUERY PLAN
---------------------------------------------------------------------------------------------
 Hash Left Join  (cost=1220.51..122913.55 rows=25332 width=56)
   Hash Cond: (COALESCE(c.sire_assoc_id, 1) = sa.assoc_id)
   CTE assoc_map
     ->  Hash Join  (cost=7.54..10.16 rows=52 width=11)
           Hash Cond: (a.country_code_2 = c_1.code_2)
           ->  Seq Scan on assoc a  (cost=0.00..1.52 rows=52 width=10)
           ->  Hash  (cost=4.46..4.46 rows=246 width=7)
                 ->  Seq Scan on country_code c_1  (cost=0.00..4.46 rows=246 width=7)
   ->  Hash Left Join  (cost=1208.66..122614.19 rows=25332 width=60)
         Hash Cond: (COALESCE(c.dam_assoc_id, 1) = da.assoc_id)
         ->  Hash Right Join  (cost=1206.97..122451.64 rows=25332 width=64)
               Hash Cond: (n.anm_key = c.anm_key)
               ->  Seq Scan on z2_raa_numbers n  (cost=0.00..61034.69 rows=3330869 width=19)
               ->  Hash  (cost=642.32..642.32 rows=25332 width=53)
                     ->  Seq Scan on carc c  (cost=0.00..642.32 rows=25332 width=53)
      ->  Hash  (cost=1.04..1.04 rows=52 width=4)
               ->  CTE Scan on assoc_map da  (cost=0.00..1.04 rows=52 width=4)
   ->  Hash  (cost=1.04..1.04 rows=52 width=4)
         ->  CTE Scan on assoc_map sa  (cost=0.00..1.04 rows=52 width=4)

也许我应该注意到我重启了,以防万一。

0 个答案:

没有答案