Not an emergency, just tracking it. From a Ctrl-A (all tracks) area selection on
the Android example trace: one selection costs ~11.5s of TP time, much of it
spent materializing and interval-intersecting the same rows more than once.
Each aggregation tab is an independent Aggregator that builds its own
extraction + _interval_intersect_single temp tables. Nothing is shared, so
tabs reading the same base data pay for it repeatedly:
- Thread state (~1.1s wasted):
thread_state_aggregation and
thread_state_by_cpu_aggregation each extract and interval-intersect the same
utid set. The by-CPU columns are a subset of the main table.
- Sched (~0.2s):
cpu_aggregation and cpu_by_process_aggregation do the
same over the same ucpu set; by-process columns are a subset of by-thread.
- Slice (~1s):
slice_aggregation's self-time path and the flamegraph path
each windowed-extract the same slices. These are genuinely different consumers.
The slowest single query is separate: the slices pivot at 2.6s,
SELECT name, sum(dur), count(1) FROM _viz_slices_for_ui_table ... GROUP BY name.
_viz_slices_for_ui_table (stdlib/viz/slices.sql) is a view built from unions
of thread/process-track joins plus slice JOIN track with track anti-joins, so
GROUP BY name re-derives the whole tree every time and ts+dur > START isn't
sargable, so nothing prunes by time first.
Top offenders from the debug SQL performance view (IN-lists elided):
| runtime_ms |
query |
| 2668 |
SELECT name, sum(dur), count(1) FROM _viz_slices_for_ui_table ... GROUP BY name |
| 1920 |
create or replace perfetto table thread_state_aggregation as ... |
| 829 |
create or replace perfetto table thread_state_by_cpu_aggregation as ... |
| 822 |
__temp_dj6be... AS _interval_intersect_single!(..., __temp_597irv...) (slice self-time) |
| 755 |
__temp_0jnl... AS _interval_intersect_single!(..., __temp_eo1rx...) (slice flamegraph) |
| 590 |
__temp_o78tb... AS thread_state WHERE utid IN (...) ORDER BY id (by_cpu extract) |
| 590 |
__temp_k36c3... AS thread_state WHERE utid IN (...) ORDER BY id (thread_state extract) |
| 501 |
__temp_hulo4... AS _interval_intersect_single!(..., __temp_k36c3...) |
| 494 |
__temp_tg24f... AS _interval_intersect_single!(..., __temp_o78tb...) |
| 490 |
create or replace perfetto table cpu_aggregation as ... |
| 417 |
create or replace perfetto table cpu_by_process_aggregation as ... |
| 358 |
__temp_597irv... AS slice WHERE track_id IN (...) ORDER BY id |
| 249 |
__temp_eo1rx... AS slice WHERE track_id IN (...) ORDER BY id |
Not an emergency, just tracking it. From a Ctrl-A (all tracks) area selection on
the Android example trace: one selection costs ~11.5s of TP time, much of it
spent materializing and interval-intersecting the same rows more than once.
Each aggregation tab is an independent
Aggregatorthat builds its ownextraction +
_interval_intersect_singletemp tables. Nothing is shared, sotabs reading the same base data pay for it repeatedly:
thread_state_aggregationandthread_state_by_cpu_aggregationeach extract and interval-intersect the sameutid set. The by-CPU columns are a subset of the main table.
cpu_aggregationandcpu_by_process_aggregationdo thesame over the same ucpu set; by-process columns are a subset of by-thread.
slice_aggregation's self-time path and the flamegraph patheach windowed-extract the same slices. These are genuinely different consumers.
The slowest single query is separate: the slices pivot at 2.6s,
SELECT name, sum(dur), count(1) FROM _viz_slices_for_ui_table ... GROUP BY name._viz_slices_for_ui_table(stdlib/viz/slices.sql) is a view built from unionsof thread/process-track joins plus
slice JOIN trackwith track anti-joins, soGROUP BY namere-derives the whole tree every time andts+dur > STARTisn'tsargable, so nothing prunes by time first.
Top offenders from the debug SQL performance view (IN-lists elided):
SELECT name, sum(dur), count(1) FROM _viz_slices_for_ui_table ... GROUP BY namecreate or replace perfetto table thread_state_aggregation as ...create or replace perfetto table thread_state_by_cpu_aggregation as ...__temp_dj6be... AS _interval_intersect_single!(..., __temp_597irv...)(slice self-time)__temp_0jnl... AS _interval_intersect_single!(..., __temp_eo1rx...)(slice flamegraph)__temp_o78tb... AS thread_state WHERE utid IN (...) ORDER BY id(by_cpu extract)__temp_k36c3... AS thread_state WHERE utid IN (...) ORDER BY id(thread_state extract)__temp_hulo4... AS _interval_intersect_single!(..., __temp_k36c3...)__temp_tg24f... AS _interval_intersect_single!(..., __temp_o78tb...)create or replace perfetto table cpu_aggregation as ...create or replace perfetto table cpu_by_process_aggregation as ...__temp_597irv... AS slice WHERE track_id IN (...) ORDER BY id__temp_eo1rx... AS slice WHERE track_id IN (...) ORDER BY id