Ho una tabella Redshift completamente aspirata da ~ 2 TB con un distkey phash
(cardinalità elevata, centinaia di milioni di valori) e tasti di selezione composti (phash, last_seen)
.Ottimizza la condizione IN grossa per la query Redshift
Quando faccio una query come:
SELECT
DISTINCT ret_field
FROM
table
WHERE
phash IN (
'5c8615fa967576019f846b55f11b6e41',
'8719c8caa9740bec10f914fc2434ccfd',
'9b657c9f6bf7c5bbd04b5baf94e61dae'
)
AND
last_seen BETWEEN '2015-10-01 00:00:00' AND '2015-10-31 23:59:59'
Esso restituisce molto rapidamente. Tuttavia, quando aumento il numero di hash oltre 10, Redshift converte la condizione IN da un gruppo di OR a un array, per http://docs.aws.amazon.com/redshift/latest/dg/r_in_condition.html#r_in_condition-optimization-for-large-in-lists
Il problema è quando ho un paio di dozzine di valori phash
, la query "ottimizzata" passa da meno di un secondo tempo di risposta a più di mezz'ora. In altre parole, smette di usare la chiave di ordinamento e fa una scansione completa della tabella.
Qualche idea su come posso evitare questo comportamento e mantenere l'uso degli ordinamenti per mantenere la query rapida?
Qui è la differenza tra EXPLAIN
< 10 hash e> 10 hash:
Meno di 10 (0,4 secondi):
XN Unique (cost=0.00..157253450.20 rows=43 width=27)
-> XN Seq Scan on table (cost=0.00..157253393.92 rows=22510 width=27)
Filter: ((((phash)::text = '394e9a527f93377912cbdcf6789787f1'::text) OR ((phash)::text = '4534f9f8f68cc937f66b50760790c795'::text) OR ((phash)::text = '5c8615fa967576019f846b55f11b6e61'::text) OR ((phash)::text = '5d5743a86b5ff3d60b133c6475e7dce0'::text) OR ((phash)::text = '8719c8caa9740bec10f914fc2434cced'::text) OR ((phash)::text = '9b657c9f6bf7c5bbd04b5baf94e61d9e'::text) OR ((phash)::text = 'd7337d324be519abf6dbfd3612aad0c0'::text) OR ((phash)::text = 'ea43b04ac2f84710dd1f775efcd5ab40'::text)) AND (last_seen >= '2015-10-01 00:00:00'::timestamp without time zone) AND (last_seen <= '2015-10-31 23:59:59'::timestamp without time zone))
Più di 10 (45-60 minuti):
XN Unique (cost=0.00..181985241.25 rows=1717530 width=27)
-> XN Seq Scan on table (cost=0.00..179718164.48 rows=906830708 width=27)
Filter: ((last_seen >= '2015-10-01 00:00:00'::timestamp without time zone) AND (last_seen <= '2015-10-31 23:59:59'::timestamp without time zone) AND ((phash)::text = ANY ('{33b84c5775b6862df965a0e00478840e,394e9a527f93377912cbdcf6789787f1,3d27b96948b6905ffae503d48d75f3d1,4534f9f8f68cc937f66b50760790c795,5a63cd6686f7c7ed07a614e245da60c2,5c8615fa967576019f846b55f11b6e61,5d5743a86b5ff3d60b133c6475e7dce0,8719c8caa9740bec10f914fc2434cced,9b657c9f6bf7c5bbd04b5baf94e61d9e,d7337d324be519abf6dbfd3612aad0c0,dbf4c743832c72e9c8c3cc3b17bfae5f,ea43b04ac2f84710dd1f775efcd5ab40,fb4b83121cad6d23e6da6c7b14d2724c}'::text[])))
non ci sto capendo quando si dice Redshift esegue sempre una scansione completa della tabella, ma potrebbe utilizzare la chiave di ordinamento per saltare i blocchi. Puoi fornire la spiegazione esatta della query? –
Nessun problema @MarkHildreth - Ho appena modificato il post principale per includere le query 'EXPLAIN'. – Harry
Nota, non molto equivale a SO lettori e utenti (ma è possibile postare la soluzione qui): esiste una mailing list dedicata per le domande sulle prestazioni postgresql. –