PostgreSQL: запрос выполняется очень медленно при первом запуске, быстро при последующих запусках

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

Это объяснение первого запуска запроса: http://explain.depesz.com/s/NdTV

Aggregate  (cost=1056.860..1056.870 rows=1 width=0) (actual time=356.740..356.740 rows=1 loops=1)
    Output: five_two(*)
    Buffers: shared hit=331 read=508
  ->  Nested Loop  (cost=935.080..1056.860 rows=1 width=0) (actual time=292.458..356.712 rows=71 loops=1)
          Buffers: shared hit=331 read=508
        ->  Nested Loop  (cost=935.080..1051.990 rows=1 width=4) (actual time=292.440..356.116 rows=71 loops=1)
                Output: xray_oscar.zulu_lima
                Buffers: shared hit=136 read=490
              ->  HashAggregate  (cost=935.080..935.090 rows=1 width=4) (actual time=282.669..282.673 rows=8 loops=1)
                      Output: foxtrot_echo.quebec
                      Buffers: shared hit=80 read=458
                    ->  Sort  (cost=935.060..935.070 rows=1 width=8) (actual time=282.661..282.662 rows=8 loops=1)
                            Output: foxtrot_echo.quebec, foxtrot_echo.five_echo
                            Sort Key: foxtrot_echo.five_echo
                            Sort Method: quicksort  Memory: 25kB
                            Buffers: shared hit=80 read=458
                          ->  Nested Loop  (cost=0.000..935.050 rows=1 width=8) (actual time=110.522..282.639 rows=8 loops=1)
                                  Output: foxtrot_echo.quebec, foxtrot_echo.five_echo
                                  Buffers: shared hit=80 read=458
                                ->  Seq Scan on charlie_hotel_yankee  (cost=0.000..870.560 rows=6 width=4) (actual time=1.880..5.777 rows=35 loops=1)
                                        Output: seven_charlie.quebec, seven_charlie.foxtrot_mike, seven_charlie."foxtrot_india", seven_charlie.yankee, seven_charlie.seven_papa, seven_charlie.romeo_hotel, seven_charlie.foxtrot_two, seven_charlie.golf, seven_charlie.kilo_seven, seven_charlie.four
                                        Filter: ((NOT seven_charlie.golf) AND (seven_charlie.yankee = 14732))
                                        Rows Removed by Filter: 38090
                                        Buffers: shared hit=2 read=392
                                ->  Index Scan using xray_bravo on delta_charlie  (cost=0.000..10.740 rows=1 width=12) (actual time=7.908..7.908 rows=0 loops=35)
                                        Output: foxtrot_echo.quebec, foxtrot_echo.uniform, foxtrot_echo.seven_papa, foxtrot_echo.romeo_hotel, foxtrot_echo.five_echo
                                        Index Cond: (foxtrot_echo.uniform = seven_charlie.quebec)
                                        Filter: ((foxtrot_echo.five_echo >= 'three'::date) AND (foxtrot_echo.five_echo <= 'november_foxtrot_golf'::date))
                                        Rows Removed by Filter: 7
                                        Buffers: shared hit=78 read=66
              ->  Index Scan using whiskey_papa on xray_india  (cost=0.000..116.890 rows=1 width=8) (actual time=1.267..9.176 rows=9 loops=8)
                      Output: xray_oscar.quebec, xray_oscar.foxtrot_mike, xray_oscar.foxtrot_tango, xray_oscar.seven_papa, xray_oscar.romeo_hotel, xray_oscar.zulu_lima, xray_oscar.lima_five, xray_oscar.bravo, xray_oscar.mike, xray_oscar.papa_hotel, xray_oscar.papa_romeo, delta_lima (...)
                      Index Cond: (xray_oscar.lima_five = foxtrot_echo.quebec)
                      Filter: ((xray_oscar.charlie_hotel_foxtrot & 1) = 0)
                      Buffers: shared hit=56 read=32
        ->  Index Scan using kilo_whiskey on seven_echo  (cost=0.000..4.860 rows=1 width=4) (actual time=0.007..0.007 rows=1 loops=71)
                Output: lima_november.quebec, lima_november.seven_papa, lima_november.romeo_hotel, lima_november.victor, lima_november.november_foxtrot_victor, lima_november.romeo_charlie, lima_november.whiskey_lima, lima_november.hotel, lima_november.sierra, lima_november.alpha, lima_november.zulu_yankee (...)
                Index Cond: (lima_november.quebec = xray_oscar.zulu_lima)
                Filter: (lima_november.yankee = 14732)
                Buffers: shared hit=195 read=18

А вот следующие быстрые прогоны: http://explain.depesz.com/s/K1J5

Aggregate  (cost=1056.860..1056.870 rows=1 width=0) (actual time=5.783..5.783 rows=1 loops=1)
    Output: five_two(*)
    Buffers: shared hit=366 read=473
  ->  Nested Loop  (cost=935.080..1056.860 rows=1 width=0) (actual time=5.516..5.770 rows=71 loops=1)
          Buffers: shared hit=366 read=473
        ->  Nested Loop  (cost=935.080..1051.990 rows=1 width=4) (actual time=5.505..5.622 rows=71 loops=1)
                Output: xray_oscar.zulu_lima
                Buffers: shared hit=156 read=470
              ->  HashAggregate  (cost=935.080..935.090 rows=1 width=4) (actual time=5.496..5.496 rows=8 loops=1)
                      Output: foxtrot_echo.quebec
                      Buffers: shared hit=85 read=453
                    ->  Sort  (cost=935.060..935.070 rows=1 width=8) (actual time=5.490..5.491 rows=8 loops=1)
                            Output: foxtrot_echo.quebec, foxtrot_echo.five_echo
                            Sort Key: foxtrot_echo.five_echo
                            Sort Method: quicksort  Memory: 25kB
                            Buffers: shared hit=85 read=453
                          ->  Nested Loop  (cost=0.000..935.050 rows=1 width=8) (actual time=3.565..5.480 rows=8 loops=1)
                                  Output: foxtrot_echo.quebec, foxtrot_echo.five_echo
                                  Buffers: shared hit=85 read=453
                                ->  Seq Scan on charlie_hotel_yankee  (cost=0.000..870.560 rows=6 width=4) (actual time=1.865..5.170 rows=35 loops=1)
                                        Output: seven_charlie.quebec, seven_charlie.foxtrot_mike, seven_charlie."foxtrot_india", seven_charlie.yankee, seven_charlie.seven_papa, seven_charlie.romeo_hotel, seven_charlie.foxtrot_two, seven_charlie.golf, seven_charlie.kilo_seven, seven_charlie.four
                                        Filter: ((NOT seven_charlie.golf) AND (seven_charlie.yankee = 14732))
                                        Rows Removed by Filter: 38090
                                        Buffers: shared hit=1 read=393
                                ->  Index Scan using xray_bravo on delta_charlie  (cost=0.000..10.740 rows=1 width=12) (actual time=0.008..0.008 rows=0 loops=35)
                                        Output: foxtrot_echo.quebec, foxtrot_echo.uniform, foxtrot_echo.seven_papa, foxtrot_echo.romeo_hotel, foxtrot_echo.five_echo
                                        Index Cond: (foxtrot_echo.uniform = seven_charlie.quebec)
                                        Filter: ((foxtrot_echo.five_echo >= 'three'::date) AND (foxtrot_echo.five_echo <= 'november_foxtrot_golf'::date))
                                        Rows Removed by Filter: 7
                                        Buffers: shared hit=84 read=60
              ->  Index Scan using whiskey_papa on xray_india  (cost=0.000..116.890 rows=1 width=8) (actual time=0.004..0.014 rows=9 loops=8)
                      Output: xray_oscar.quebec, xray_oscar.foxtrot_mike, xray_oscar.foxtrot_tango, xray_oscar.seven_papa, xray_oscar.romeo_hotel, xray_oscar.zulu_lima, xray_oscar.lima_five, xray_oscar.bravo, xray_oscar.mike, xray_oscar.papa_hotel, xray_oscar.papa_romeo, delta_lima (...)
                      Index Cond: (xray_oscar.lima_five = foxtrot_echo.quebec)
                      Filter: ((xray_oscar.charlie_hotel_foxtrot & 1) = 0)
                      Buffers: shared hit=71 read=17
        ->  Index Scan using kilo_whiskey on seven_echo  (cost=0.000..4.860 rows=1 width=4) (actual time=0.002..0.002 rows=1 loops=71)
                Output: lima_november.quebec, lima_november.seven_papa, lima_november.romeo_hotel, lima_november.victor, lima_november.november_foxtrot_victor, lima_november.romeo_charlie, lima_november.whiskey_lima, lima_november.hotel, lima_november.sierra, lima_november.alpha, lima_november.zulu_yankee (...)
                Index Cond: (lima_november.quebec = xray_oscar.zulu_lima)
                Filter: (lima_november.yankee = 14732)
                Buffers: shared hit=210 read=3

Я знаю, что Postgres всегда будет работать немного быстрее при последующих запросах по сравнению с первым, когда он его запускает, но я не думал, что это будет настолько существенной разницей. Использование других фильтров идентификаторов клиентов (lima_november.yankee в запросе) Я видел, как один запрос выполнялся быстро за 12 мс и медленно за 1873 мс. Так что это довольно глубокая разница.

Запрос выбирает счетчик из таблицы с примерно 2 миллионами строк на основе трех фильтров. Первый - это идентификатор клиента, который выполняется через объединение, то есть сканирование индекса в нижней части планов запросов. Второй запрос IN, который, кажется, что индекс сканирования whiskey_papa делается. Третье побитовое утверждение - (xray_oscar.charlie_hotel_foxtrot & 1) = 0,

Я не видел buffers вывод explain analyze раньше, так что не знаю, с чего начать читать. Кажется странным, что вложенный цикл в позиции 6 в медленном запросе имеет фактическое время, настолько отличное от строк, вложенных в него. Но я не знаю, как это улучшить (или если это даже главная проблема).

Эти тесты находятся на postgres 9.2.13 на OS X 10.11.1. Какие-нибудь советы?

0 ответов

Другие вопросы по тегам