Nous avons une table simple Redshift qui stocke les données de séries chronologiques semi-structurées:Rejoindre des événements de journaux associés dans Redshift?
Table "public.system_log_lines"
Column | Type | Modifiers
--------------+-----------------------------+-----------
id | bigint | not null
received_at | timestamp without time zone | not null
program | character varying(64) |
message | character varying(65535) |
Indexes:
"system_log_lines_new_pkey" PRIMARY KEY, btree (id)
Son sortkey est received_at
:
table | diststyle | sortkey1 | skew_sortkey1
------------------------+-----------+-------------+---------------
system_log_lines | EVEN | received_at | 60.26
Une question commune au sujet de ces données: « ce que les événements se produisent peu de temps après un type particulier d'événement inhabituel? ".
Exprimant ce type de question dans SQL est simple:
select
first_lines.received_at,
more_lines.*
from (
select
log.received_at,
log.program,
log.message
from system_log_lines as log
where
log.program = 'something.log'
and log.message like '%SOME INTERESTING STRING%'
) as first_lines
left join system_log_lines as more_lines on
more_lines.received_at between
first_lines.received_at
and first_lines.received_at + '1 minute'::interval
;
Cependant, Redshift est incapable d'exécuter cette requête avec succès. Il ne se termine jamais lors de la course dans la pratique. Voici le plan de requête produit:
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
XN Nested Loop Left Join DS_BCAST_INNER (cost=0.00..64217501937184.91 rows=2973033 width=237)
Join Filter: (("inner".received_at <= ("outer".received_at + '00:01:00'::interval)) AND ("inner".received_at >= "outer".received_at))
-> XN Seq Scan on system_log_lines log (cost=0.00..401359.38 rows=1 width=8)
Filter: (((message)::text ~~ '%SOME INTERESTING STRING%'::text) AND ((program)::text = 'something.log'::text))
-> XN Seq Scan on system_log_lines more_lines (cost=0.00..267572.92 rows=26757292 width=229)
----- Nested Loop Join in the query plan - review the join predicates to avoid Cartesian products -----
(6 rows)
La jointure est inefficace. Ce n'est pas surprenant étant donné la condition BETWEEN
. Ce qui est est que la requête ne parvient toujours pas à se terminer même si un LIMIT 1
explicite est appliqué à la sous-sélection (c.-à-d. Qu'il n'y a qu'un seul "événement inhabituel" à joindre). Ou même si aucune ligne n'est renvoyée par cette sous-sélection (c.-à-d. Qu'il n'y a aucun événement auquel participer).
Cela semble bizarre puisque la même requête ne fin si l'JOIN
est retirée, en utilisant des conditions received_at
littérales, donc il semble que même une simple jointure de boucle imbriquée de mise en œuvre (par exemple, l'exécution de la boucle se joindre à la couche d'application) pourrait travailler de façon acceptable.
Existe-t-il un moyen de structurer ce type de requête de sorte que Redshift puisse l'exécuter avec succès?