Отличается план исполнения одного и того же запроса

Wicked

Новичок
Отличается план исполнения одного и того же запроса

... когда я его выполняю из psql и когда он выполняется из php.
Различие по cost - в 150 раз.

Есть какие-то причины на поверхности? В какую сторону копать?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Миелофон в ремонте, поэтому хотелось бы увидеть запрос, то, как он выполняется из PHP и оба плана.
 

Wicked

Новичок
Не вопрос. Просто наверное есть какие-то общие соображения. Сейчас попытаюсь задампить "show all" там и там и сравнить.

Код:
 select
   uf.id AS user_feed_id,
   count(*) as c
 from
   ext_feeder_item fi
   inner join ext_feeder_user_feed as uf
     on (uf.feed_id = fi.feed_id)
   inner join ext_feeder_feed as f
     on (f.id = fi.feed_id)
   left join ext_feeder_item_status as fs
     on ((fs.item_id = fi.id) and (fs.feeder_id = uf.feeder_id))
 where
   NOT CASE WHEN fs.status IS NULL THEN
     -- before any possible real horizont_dates
     fi.pub_date < COALESCE(f.horizont_date, CAST('1981-01-01 00:00+00' AS TIMESTAMP WITH TIME ZONE))
   ELSE
     fs.status = 1
   END
 and
   uf.id in (1531,...~1000 штук...,119901)
 group by uf.id
 having count(*) > 0
psql:
Код:
 HashAggregate  (cost=5784.85..5804.75 rows=1137 width=8) (actual time=283.397..283.452 rows=27 loops=1)
   Filter: (count(*) > 0)
   ->  Merge Right Join  (cost=5610.39..5761.18 rows=3156 width=8) (actual time=275.987..283.153 rows=107 loops=1)
         Merge Cond: ((fs.item_id = fi.id) AND (fs.feeder_id = uf.feeder_id))
         Filter: (NOT CASE WHEN (fs.status IS NULL) THEN (fi.pub_date < COALESCE(f.horizont_date, '1981-01-01 07:00:00+07'::timestamp with time zone)) ELSE (fs.status = 1) END)
         ->  Index Scan using ext_feeder_item_status_pkey on ext_feeder_item_status fs  (cost=0.00..709.40 rows=15872 width=20) (actual time=0.057..4.002 rows=2294 loops=1)
         ->  Sort  (cost=5610.39..5626.18 rows=6313 width=40) (actual time=275.209..275.425 rows=192 loops=1)
               Sort Key: fi.id, uf.feeder_id
               Sort Method:  quicksort  Memory: 30kB
               ->  Merge Join  (cost=3873.49..5211.91 rows=6313 width=40) (actual time=185.397..274.643 rows=192 loops=1)
                     Merge Cond: (uf.feed_id = fi.feed_id)
                     ->  Merge Join  (cost=0.00..20185.31 rows=1137 width=40) (actual time=0.446..35.747 rows=63 loops=1)
                           Merge Cond: (uf.feed_id = f.id)
                           ->  Index Scan using ext_feeder_user_feed_feed_id_idx on ext_feeder_user_feed uf  (cost=0.00..19059.96 rows=1137 width=24) (actual time=0.385..34.281 rows=63 loops=1)
                                 Filter: (id = ANY ('{1531,...~1000 штук...,119901}'::bigint[]))
                           ->  Index Scan using ext_feeder_feed_pkey on ext_feeder_feed f  (cost=0.00..1089.93 rows=9386 width=16) (actual time=0.047..0.722 rows=266 loops=1)
                     ->  Sort  (cost=3873.49..3925.20 rows=20684 width=24) (actual time=184.939..214.999 rows=20684 loops=1)
                           Sort Key: fi.feed_id
                           Sort Method:  external sort  Disk: 808kB
                           ->  Seq Scan on ext_feeder_item fi  (cost=0.00..2390.84 rows=20684 width=24) (actual time=0.014..67.411 rows=20684 loops=1)
 Total runtime: 285.230 ms
PHP:
Код:
 HashAggregate  (cost=857902.44..857922.33 rows=1137 width=8) (actual time=117884.130..117884.748 rows=347 loops=1)
  Filter: (count(*) > 0)
  ->  Merge Left Join  (cost=851326.25..855750.06 rows=286983 width=8) (actual time=117864.712..117881.142 rows=1498 loops=1)
        Merge Cond: ((uf.feeder_id = fs.feeder_id) AND (fi.id = fs.item_id))
        Filter: (NOT CASE WHEN (fs.status IS NULL) THEN (fi.pub_date < COALESCE(f.horizont_date, '1981-01-01 00:00:00+00'::timestamp with time zone)) ELSE (fs.status = 1) END)
        ->  Sort  (cost=849966.12..851401.04 rows=573966 width=40) (actual time=117765.294..117770.588 rows=4814 loops=1)
              Sort Key: uf.feeder_id, fi.id
              Sort Method:  quicksort  Memory: 467kB
              ->  Hash Join  (cost=461568.34..763669.54 rows=573966 width=40) (actual time=86584.199..117741.915 rows=4814 loops=1)
                    Hash Cond: (uf.feed_id = fi.feed_id)
                    ->  Hash Join  (cost=4677.90..6517.40 rows=1137 width=40) (actual time=56.363..64.782 rows=1192 loops=1)
                          Hash Cond: (uf.feed_id = f.id)
                          ->  Bitmap Heap Scan on ext_feeder_user_feed uf  (cost=4152.71..5965.21 rows=1137 width=24) (actual time=15.457..17.221 rows=1192 loops=1)
                                Recheck Cond: (id = ANY ('{1531,...~1000 штук...,119901}'::bigint[]))
                                ->  Bitmap Index Scan on ext_feeder_user_feed_pkey  (cost=0.00..4152.43 rows=1137 width=0) (actual time=15.434..15.434 rows=1192 loops=1)
                                      Index Cond: (id = ANY ('{1531,...~1000 штук...,119901}'::bigint[]))
                          ->  Hash  (cost=407.86..407.86 rows=9386 width=16) (actual time=40.869..40.869 rows=9386 loops=1)
                                ->  Seq Scan on ext_feeder_feed f  (cost=0.00..407.86 rows=9386 width=16) (actual time=0.017..22.830 rows=9386 loops=1)
                    ->  Hash  (cost=396938.42..396938.42 rows=3265442 width=24) (actual time=86109.247..86109.247 rows=3282823 loops=1)
                          ->  Seq Scan on ext_feeder_item fi  (cost=0.00..396938.42 rows=3265442 width=24) (actual time=0.049..76679.642 rows=3282823 loops=1)
        ->  Sort  (cost=1360.13..1399.81 rows=15872 width=20) (actual time=87.817..93.294 rows=5367 loops=1)
              Sort Key: fs.feeder_id, fs.item_id
              Sort Method:  quicksort  Memory: 877kB
              ->  Seq Scan on ext_feeder_item_status fs  (cost=0.00..252.72 rows=15872 width=20) (actual time=2.782..41.988 rows=15872 loops=1)
Total runtime: 117904.944 ms
-~{}~ 21.04.08 16:11:

вообще сам этот запрос лично для меня выглядит как-то странно, но спросить у программиста уточнений в ближайщие дни не смогу

-~{}~ 21.04.08 16:38:

сравнил "show all" - разница только в timezone.

если меняю ее в psql на соотвутствующую (set time zone 'UTC';), проблема остается.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Я вощемта вижу следующее, в версии от psql
Код:
Seq Scan on ext_feeder_item fi  (cost=0.00..2390.84 rows=20684 width=24) (actual time=0.014..67.411 rows=20684 loops=1)
а в версии от PHP
Код:
Seq Scan on ext_feeder_item fi  (cost=0.00..396938.42 rows=3265442 width=24) (actual time=0.049..76679.642 rows=3282823 loops=1)
Как бы записей в таблице слегка больше стало?

И не игрались ли вы случайно с параметром "join_collapse_limit"?

И условие в WHERE могуче странное... Лучше попробовать как-то по-другому сформулировать.
 

Wicked

Новичок
Как бы записей в таблице слегка больше стало?
разве что используются разные базы. Сейчас удостоверюсь.

И не игрались ли вы случайно с параметром "join_collapse_limit"?
Нет. join_collapse_limit = 8 в обоих случаях.

И условие в WHERE могуче странное... Лучше попробовать как-то по-другому сформулировать.
Чуток попозже попробую.

-~{}~ 22.04.08 11:48:

разве что используются разные базы. Сейчас удостоверюсь.
именно так :(
похоже как-то импортил дамп и забыл указать базу, и оно залилось в стандартную

-~{}~ 22.04.08 20:55:

путем денормализации и разбиения запроса на 2 добился суммарного cost около 1100
 
Сверху