2017-01-26 2 views
1

Beispieldaten aus meinem Tisch test_table:Langsam WHERE IN Ende der Abfrage

date   symbol  value  created_time 
2010-01-09  symbol1  101  3847474847 
2010-01-10  symbol1  102  3847474847 
2010-01-10  symbol1  102.5  3847475500 
2010-01-10  symbol2  204  3847474847 
2010-01-11  symbol1  109  3847474847 
2010-01-12  symbol1  105  3847474847 
2010-01-12  symbol2  206  3847474847 

Unten ist die Abfrage, die ich zur Zeit mit etwa 3k eindeutigen Symbolen und etwa 11 Millionen Zeilen auf einem Tisch verwenden. Es dauert noch eine Weile (über 80% der Abfragezeit wird für den Unterabfrage-Scan am Ende verwendet (was ich denke, ist die WHERE IN-Klausel am Ende der Abfrage. Gibt es irgendeine Möglichkeit, diesen Teil zu beschleunigen (imagine) ich habe eine Menge von Symbolen in der WHERE iN-Lookup)

select date, symbol, value, created_time 
from (select *, 
    rank() over (partition by date, symbol order by created_time desc) as rownum 
    from test_table) x 
where rownum = 1 and symbol in ('symbol1', 'symbol2', 'symbol5', ...) 

im Folgenden eine EXPLAIN ausgegeben ANALYZE, ob das hilft

QUERY PLAN 
Subquery Scan on x (cost=281573.35..282473.76 rows=129 width=37) (actual time=2874.389..3037.008 rows=32393 loops=1) 
    Filter: (x.rownum = 1) 
    Rows Removed by Filter: 183 
    -> WindowAgg (cost=281573.35..282152.19 rows=25726 width=37) (actual time=2874.363..2980.848 rows=32576 loops=1) 
     -> Sort (cost=281573.35..281637.67 rows=25726 width=37) (actual time=2874.340..2901.443 rows=32576 loops=1) 
       Sort Key: "test_table".date, "test_table".symbol, "test_table".created_time DESC 
       Sort Method: quicksort Memory: 3314kB 
       -> Seq Scan on "test_table" (cost=0.00..279688.80 rows=25726 width=37) (actual time=118.338..2693.767 rows=32576 loops=1) 
        Filter: (symbol = ANY ('{symbol5,symbol8,symbol15,symbol98,symbol43,symbol908}'::text[])) 
        Rows Removed by Filter: 10649132 
Planning time: 0.999 ms 
Execution time: 3064.496 ms 
+0

Ranking ist keine billige Operation ... –

+0

Sie könnten sich einer Tabelle anschließen, die die Symbole enthält, aber ich denke, es gibt keinen vollständigen Tabellenscan auf 'test_table'. –

Antwort

1

Versuchen Sie es mit distinct on statt:..

select distinct on (symbol, date) date, symbol, value, created_time 
from test_table 
where symbol in ('symbol1', 'symbol2', 'symbol5', ...) 
order by symbol, date, created_time desc; 

Und zum Bei dieser Abfrage möchten Sie einen Index für test_table(symbol, date, created_time desc).

+0

Hmmm aus irgendeinem Grund gibt mir das nur eine Handvoll von Werten, anstatt das, was ich suche ... alle Kombinationen von Datum und Symbol im Maximum created_time –

+0

@TrevorNederlof. . . Es sollte jetzt funktionieren. –

+0

So viel schneller, das hat wirklich den Trick gemacht. Danke, dass du geduldig mit mir bist und mir die Kraft von distinct auf zeigst, werde sicher mehr in die Details lesen und es in der Zukunft benutzen. Danke nochmal. –