Re: SELECT LIMIT 1 VIEW Performance Issue - Mailing list pgsql-performance

From K C Lau
Subject Re: SELECT LIMIT 1 VIEW Performance Issue
Date
Msg-id 6.2.1.2.0.20050922102035.07bcf2e0@localhost
Whole thread Raw
In response to SELECT LIMIT 1 VIEW Performance Issue  (K C Lau <kclau60@netvigator.com>)
Responses Re: SELECT LIMIT 1 VIEW Performance Issue
List pgsql-performance
Hi All,

Investigating further on this problem I brought up in June, the following
query with pg 8.0.3 on Windows scans all 1743 data records for a player:

esdt=> explain analyze select PlayerID,AtDate from Player a
  where PlayerID='22220' and AtDate = (select b.AtDate from Player b
  where b.PlayerID = a.PlayerID order by b.PlayerID desc, b.AtDate desc
LIMIT 1);

  Index Scan using pk_player on player a  (cost=0.00..2789.07 rows=9
width=23) (a
ctual time=51.046..51.049 rows=1 loops=1)
    Index Cond: ((playerid)::text = '22220'::text)
    Filter: ((atdate)::text = ((subplan))::text)
    SubPlan
      ->  Limit  (cost=0.00..0.83 rows=1 width=23) (actual
time=0.016..0.017 rows
=1 loops=1743)
            ->  Index Scan Backward using pk_player on player
b  (cost=0.00..970.
53 rows=1166 width=23) (actual time=0.011..0.011 rows=1 loops=1743)
                  Index Cond: ((playerid)::text = ($0)::text)
  Total runtime: 51.133 ms

Using a static value in the subquery produces the desired result below, but
since we use views for our queries (see last part of this email), we cannot
push the static value into the subquery:

esdt=> explain analyze select PlayerID,AtDate from Player a
  where PlayerID='22220' and AtDate = (select b.AtDate from Player b
  where b.PlayerID = '22220' order by b.PlayerID desc, b.AtDate desc LIMIT 1);

  Index Scan using pk_player on player a  (cost=0.75..4.26 rows=1 width=23)
(actu
al time=0.054..0.058 rows=1 loops=1)
    Index Cond: (((playerid)::text = '22220'::text) AND ((atdate)::text =
($0)::t
ext))
    InitPlan
      ->  Limit  (cost=0.00..0.75 rows=1 width=23) (actual
time=0.028..0.029 rows
=1 loops=1)
            ->  Index Scan Backward using pk_player on player
b  (cost=0.00..1323
.05 rows=1756 width=23) (actual time=0.023..0.023 rows=1 loops=1)
                  Index Cond: ((playerid)::text = '22220'::text)
  Total runtime: 0.149 ms

The Player table has a primary key on PlayerID, AtDate. Is there a way to
stop the inner-most index scan looping all 1743 data records for that
player?  Is that a bug or known issue?

BTW, I tried using 8.1 beta2 on Windows and its performance is similar, I
have also tried other variants such as MAX and DISTINCT but with no success.

Any help is most appreciated.

Best regards,
KC.


At 10:46 05/06/15, K C Lau wrote:
>Hi All,
>
>I previously posted the following as a sequel to my SELECT DISTINCT
>Performance Issue question. We would most appreciate any clue or
>suggestions on how to overcome this show-stopping issue. We are using
>8.0.3 on Windows.
>
>Is it a known limitation when using a view with SELECT ... LIMIT 1?
>
>Would the forthcoming performance enhancement with MAX help when used
>within a view, as in:
>
>create or replace view VCurPlayer as select * from Player a
>where a.AtDate = (select Max(b.AtDate) from Player b where a.PlayerID =
>b.PlayerID);
>
>select PlayerID,AtDate from VCurPlayer where PlayerID='22220';
>
>Thanks and regards,
>KC.
>
>---------
>
>Actually the problem with LIMIT 1 query is when we use views with the
>LIMIT 1 construct. The direct SQL is ok:
>
>esdt=> explain analyze select PlayerID,AtDate from Player where
>PlayerID='22220'
>  order by PlayerID desc, AtDate desc LIMIT 1;
>
>  Limit  (cost=0.00..1.37 rows=1 width=23) (actual time=0.000..0.000
> rows=1 loops=1)
>    ->  Index Scan Backward using pk_player on
> player  (cost=0.00..16074.23 rows=11770 width=23) (actual
> time=0.000..0.000 rows=1 loops=1)
>          Index Cond: ((playerid)::text = '22220'::text)
>  Total runtime: 0.000 ms
>
>esdt=> create or replace view VCurPlayer3 as select * from Player a
>where AtDate = (select b.AtDate from Player b where a.PlayerID = b.PlayerID
>order by b.PlayerID desc, b.AtDate desc LIMIT 1);
>
>esdt=> explain analyze select PlayerID,AtDate,version from VCurPlayer3
>where PlayerID='22220';
>  Index Scan using pk_player on player a  (cost=0.00..33072.78 rows=59
> width=27)
>(actual time=235.000..235.000 rows=1 loops=1)
>    Index Cond: ((playerid)::text = '22220'::text)
>    Filter: ((atdate)::text = ((subplan))::text)
>    SubPlan
>      ->  Limit  (cost=0.00..1.44 rows=1 width=23) (actual
> time=0.117..0.117 rows=1 loops=1743)
>            ->  Index Scan Backward using pk_player on player
> b  (cost=0.00..14023.67 rows=9727 width=23) (actual time=0.108..0.108
> rows=1 loops=1743)
>                  Index Cond: (($0)::text = (playerid)::text)
>  Total runtime: 235.000 ms


pgsql-performance by date:

Previous
From: Tom Lane
Date:
Subject: Re: Query slower on 8.0.3 (Windows) vs 7.3 (cygwin)
Next
From: Simon Riggs
Date:
Subject: Re: Nested Loop trouble : Execution time increases more