Skip to content

Show query state and timings while waiting - #2278

Merged
rolandwalker merged 1 commit into
mainfrom
RW/show-query-status-in-foreground-with-rendering
Sep 29, 2026
Merged

rolandwalker merged 1 commit into
mainfrom
RW/show-query-status-in-foreground-with-rendering

Conversation

@rolandwalker

@rolandwalker rolandwalker commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

While a query is running, and while output is prepared, the current mycli UI is entirely blank. (Less than a lack of feedback: the prompt-toolkit toolbar even disappears.)

Better practice would be to tell the user what is happening. Here we run the MySQL query in a thread, and print the query state every half-second by default. Nothing is displayed until the half-second interval is reached.

The state is accompanied by the elapsed time. A spinner from yaspinner was also considered. A spinner is more tidy; the timings give more information.

The query-state string is derived from running SHOW PROCESSLIST in a separate monitoring connection, and a few pseudo-states are added beyond those listed in

including the important pseudo-state rendering, which we learned here can take a substantial amount of time for results on the order of 100K rows or above.

The official MySQL thread states are very inconsistent on casing, which looked janky, so all are rendered as lowercase.

Care is taken to catch interrupts and cancel background threads correctly.

The second monitoring connection is reused between queries.

There is a new file query_runner.py, outside of which impact on non-test files is happily low.

Drawbacks:

  • Only a few server states account for most of what is visible at a reasonable sampling resolution.

Suggestions for future work:

  • Remember all of the states/timings for an extended textual timing summary at the end; a simpler SHOW PROFILES.
  • Show prompt-toolkit toolbar during query (difficult).
  • Show transforms as a separate state transforming. done and force-pushed
  • It is possible to see the executing state multiple times, and not clear if that is a good thing.
  • It would be best to almost never see finding state, but it shows briefly at the start some times, in some configurations.
  • Test on exotic servers such as TiDB. The docs for TiDB and Apache Doris show support for SHOW PROCESSLIST which should be all that is needed.

Example: this video is from an early draft, but the idea is put across, including the amount of time spent on client-side rendering:

mycli_query_progress_rendering.mov

Checklist

  • I added this contribution to the changelog.md file.
  • I added my name to the AUTHORS file (or it's already there).
  • To lint and format the code, I ran
    uv run ruff check && uv run ruff format && uv run mypy --install-types .

@rolandwalker rolandwalker self-assigned this Sep 28, 2026
@rolandwalker
rolandwalker force-pushed the RW/show-query-status-in-foreground-with-rendering branch 3 times, most recently from 0d4b1a1 to 748a8bd Compare September 29, 2026 09:55
@rolandwalker rolandwalker changed the title Show query status and timings while waiting Show query state and timings while waiting Sep 29, 2026
@rolandwalker
rolandwalker force-pushed the RW/show-query-status-in-foreground-with-rendering branch 4 times, most recently from a6e0b6c to 4ee1ca7 Compare September 29, 2026 10:26
While a query is running, and while output is prepared, the current
mycli UI is entirely blank.  (Less than a lack of feedback:
the prompt-toolkit toolbar even disappears.)

Better practice would be to tell the user what is happening.  Here
we run the MySQL query in a thread, and print the query state every
half-second by default.  Nothing is displayed until the half-second
interval is reached.

The state is accompanied by the elapsed time.  A spinner from
yaspinner was also considered.  A spinner is more tidy; the timings
give more information.

The query-state string is derived from running SHOW PROCESSLIST in a
separate monitoring connection, and a few pseudo-states are added beyond
those listed in

 * https://dev.mysql.com/doc/refman/9.7/en/general-thread-states.html

including the important pseudo-state "rendering", which we learned here
can take a substantial amount of time for results on the order of 100K
rows or above.

The official MySQL thread states are very inconsistent on casing, which
looked janky, so all are rendered as lowercase.

Care is taken to catch interrupts and cancel background threads
correctly.

The second monitoring connection is reused between queries.

There is a new file query_runner.py, outside of which impact on non-
test files is happily low.

Drawbacks:

 * only a few server states account for most of what is visible at a
   reasonable sampling resolution

Suggestions for future work:

 * remember all of the states/timings for an extended textual timing
   summary at the end; a simpler SHOW PROFILES
 * show prompt-toolkit toolbar during query (difficult)
 * it is possible to see the "executing" state multiple times, and not
   clear if that is a good thing
 * it would be best to almost never see "finding state", but it shows
   briefly at the start some times, in some configurations
 * test on exotic servers such as TiDB
@rolandwalker
rolandwalker force-pushed the RW/show-query-status-in-foreground-with-rendering branch from 4ee1ca7 to d1f07c1 Compare September 29, 2026 10:30
@rolandwalker
rolandwalker merged commit 2f47998 into main Sep 29, 2026
12 checks passed
@rolandwalker
rolandwalker deleted the RW/show-query-status-in-foreground-with-rendering branch September 29, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant