Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Optimize span query based on maximum time duration
Browse files Browse the repository at this point in the history
Using the max time duration of a trace, we can optimize the query by
searching chunks only within the window of possibilites when we know
the time for one of the traces of the span.

We optimize the span, link, and event hypertable scans.

On some tests, decreased query time from 3s to 300ms.
  • Loading branch information
cevian committed May 9, 2022
1 parent 5c4a2d1 commit e7f1a6a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
3 changes: 1 addition & 2 deletions pkg/jaeger/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ import (

type Query struct {
conn pgxconn.PgxConn
cfg *Config
builder *Builder
}

func New(conn pgxconn.PgxConn, cfg *Config) *Query {
return &Query{conn, cfg, NewBuilder(cfg)}
return &Query{conn, NewBuilder(cfg)}
}

func (p *Query) SpanReader() spanstore.Reader {
Expand Down
46 changes: 34 additions & 12 deletions pkg/jaeger/query/trace_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ const (
LEFT JOIN
_ps_trace.schema_url s_url ON s.resource_schema_url_id = s_url.id
LEFT JOIN
_ps_trace.event e ON e.span_id = s.span_id AND e.trace_id = s.trace_id
_ps_trace.event e ON e.span_id = s.span_id AND e.trace_id = s.trace_id %[3]s
LEFT JOIN
_ps_trace.instrumentation_lib inst_lib ON s.instrumentation_lib_id = inst_lib.id
LEFT JOIN
_ps_trace.schema_url inst_lib_url ON inst_lib_url.id = inst_lib.schema_url_id
LEFT JOIN
_ps_trace.link lk ON lk.trace_id = s.trace_id AND lk.span_id = s.span_id
_ps_trace.link lk ON lk.trace_id = s.trace_id AND lk.span_id = s.span_id %[4]s
WHERE
%s
%[1]s %[2]s
GROUP BY
s.trace_id,
s.span_id,
Expand All @@ -78,14 +78,14 @@ const (

subqueryFormat = `
SELECT
trace_sub.trace_id
trace_sub.trace_id, start_time_max - $%[1]d::interval as time_low, start_time_max + $%[1]d::interval as time_high
FROM (
SELECT
trace_id,
max(start_time) as start_time_max
FROM _ps_trace.span s
WHERE
%s
%[2]s
GROUP BY trace_id
) as trace_sub
ORDER BY trace_sub.start_time_max DESC
Expand Down Expand Up @@ -116,16 +116,34 @@ func NewBuilder(cfg *Config) *Builder {
return &Builder{cfg}
}

func (b *Builder) buildCompleteTraceQuery(traceIDClause string) string {
func (b *Builder) buildCompleteTraceQuery(traceIDClause string, timeLowRef string, timeHighRef string) string {
spanTimeClause := ""
eventTimeClause := ""
linkTimeClause := ""
if timeLowRef != "" {
spanTimeClause += " AND s.start_time > " + timeLowRef
eventTimeClause += " AND e.time > " + timeLowRef
linkTimeClause += " AND lk.span_start_time > " + timeLowRef
}
if timeHighRef != "" {
spanTimeClause += " AND s.start_time < " + timeHighRef
eventTimeClause += " AND e.time < " + timeHighRef
linkTimeClause += " AND lk.span_start_time < " + timeHighRef
}

return fmt.Sprintf(
completeTraceSQLFormat,
traceIDClause)
traceIDClause,
spanTimeClause,
eventTimeClause,
linkTimeClause,
)
}

func (b *Builder) findTracesQuery(q *spanstore.TraceQueryParameters) (string, []interface{}) {
subquery, params := b.buildTraceIDSubquery(q)
traceIDClause := "s.trace_id = trace_ids.trace_id"
completeTraceSQL := b.buildCompleteTraceQuery(traceIDClause)
completeTraceSQL := b.buildCompleteTraceQuery(traceIDClause, "trace_ids.time_low", "trace_ids.time_high")
return fmt.Sprintf(findTraceSQLFormat, subquery, completeTraceSQL), params
}

Expand All @@ -148,7 +166,7 @@ func (b *Builder) getTraceQuery(traceID model.TraceID) (string, []interface{}, e
params := []interface{}{uuid}

traceIDClause := "s.trace_id = $1"
return b.buildCompleteTraceQuery(traceIDClause), params, nil
return b.buildCompleteTraceQuery(traceIDClause, "", ""), params, nil
}

func (b *Builder) buildTraceIDSubquery(q *spanstore.TraceQueryParameters) (string, []interface{}) {
Expand Down Expand Up @@ -228,12 +246,16 @@ func (b *Builder) buildTraceIDSubquery(q *spanstore.TraceQueryParameters) (strin

}

query := ""
clauseString := ""
if len(clauses) > 0 {
query = fmt.Sprintf(subqueryFormat, strings.Join(clauses, " AND "))
clauseString = strings.Join(clauses, " AND ")
} else {
query = fmt.Sprintf(subqueryFormat, "TRUE")
clauseString = "TRUE"
}
params = append(params, b.cfg.MaxTraceDuration)
//Note: the parameter number for b.cfg.MaxTraceDuration is used in two places ($%[1]d in subqueryFormat)
//to both add and subtract from start_time_max.
query := fmt.Sprintf(subqueryFormat, len(params), clauseString)

if q.NumTraces != 0 {
query += fmt.Sprintf(" LIMIT %d", q.NumTraces)
Expand Down

0 comments on commit e7f1a6a

Please sign in to comment.