Skip to content

feat: Improve EXPLAIN support for MySQL and PostgreSQL#2165

Open
seladb wants to merge 12 commits intotortoise:developfrom
seladb:improved-explain
Open

feat: Improve EXPLAIN support for MySQL and PostgreSQL#2165
seladb wants to merge 12 commits intotortoise:developfrom
seladb:improved-explain

Conversation

@seladb
Copy link
Copy Markdown
Contributor

@seladb seladb commented Apr 3, 2026

Improve EXPLAIN support - add output format and explain options for supported databases (PostgreSQL and MySQL)

Description

  • MySQL executor: Added execute_explain() with support for FORMAT (JSON, TRADITIONAL, TREE) and ANALYZE options
  • PostgreSQL executor: Enhanced with multiple output formats (TEXT, JSON, XML, YAML) and options (ANALYZE, BUFFERS, COSTS, MEMORY, SETTINGS, SERIALIZE, SUMMARY, TIMING, VERBOSE, WAL)
  • Base executor: Added proper error handling for unsupported formats/options
  • QuerySet API: Updated explain() method to accept output_fmt and additional options

Motivation and Context

Previously, the explain() method had limited functionality. This adds comprehensive EXPLAIN support for MySQL and PostgreSQL, allowing users to get detailed query execution plans in multiple formats and with various options.

How Has This Been Tested?

Added the following tests:

  • Tests for MySQL EXPLAIN (JSON, traditional, tree formats, analyze)
  • Tests for PostgreSQL EXPLAIN (various formats and all options)
  • Tests for unsupported formats/options error handling

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added the changelog accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

- Implement execute_explain() in mysql/executor.py with support for
  FORMAT (JSON, TRADITIONAL, TREE) and ANALYZE options
- Update base_executor to raise proper errors for unsupported formats/options
- Add comprehensive tests for explain() in test_postgres.py, test_mysql.py,
  and test_explain.py covering various formats and options
- Add error handling for unsupported options in MySQL executor
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 3, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing seladb:improved-explain (6a7e7d4) with develop (9d0e53e)

Open in CodSpeed

@seladb
Copy link
Copy Markdown
Contributor Author

seladb commented Apr 3, 2026

@abondar I'm not sure why MSSQL tests fail randomly, but it's not related to the changes in this PR

@seladb seladb marked this pull request as ready for review April 3, 2026 08:06
@seladb
Copy link
Copy Markdown
Contributor Author

seladb commented Apr 10, 2026

@abondar this PR is also ready for review! 🙏

@seladb
Copy link
Copy Markdown
Contributor Author

seladb commented Apr 25, 2026

@abondar this PR is also ready for review! 🙏

@abondar @waketzheng a gentle reminder to review this PR 🙏

raise UnSupportedError(f"Unsupported options: {unsupported_options}")

required_options.add("FORMAT " + output_fmt.upper())
postrges_options = ", ".join(required_options)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo? postgres not postrges

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixed in 042d901

Comment thread tortoise/backends/mysql/executor.py Outdated
posix_regex: mysql_posix_regex,
}
EXPLAIN_PREFIX = "EXPLAIN FORMAT=JSON"
EXPLAIN_PREFIX = "EXPLAIN {}"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overriden EXPLAIN_PREFIX is not used anywhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. Removed in 6a7e7d4

Comment thread tortoise/queryset.py
Comment on lines -1065 to +1066
- PostgreSQL: ``EXPLAIN (FORMAT JSON, VERBOSE) ...``
- SQLite: ``EXPLAIN QUERY PLAN ...``
- MySQL: ``EXPLAIN FORMAT=JSON ...``
:param output_fmt: The output format for the EXPLAIN result.
- PostgreSQL: ``text``, ``json``, ``xml``, ``yaml`` (default: ``json``)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do I understand correctly that we lost default "VERBOSE" for pg here? Is it intended? Do you think verbose is bad default option?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added back VERBOSE as a default option if no options are provided in this commit: 042d901

@seladb
Copy link
Copy Markdown
Contributor Author

seladb commented May 2, 2026

@abondar thanks for the PR review. I addressed all the comments, can you please re-review?

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.

2 participants