Database query performance is one of the most common bottlenecks in production systems. Sometimes the query optimizer makes sub-optimal choices — selecting a sequential scan when an index scan would be faster, or joining tables in the wrong order. Query rewrite tools let you override or redirect problematic queries without modifying application code.
In this guide, we compare three self-hosted query rewrite solutions: PostgreSQL’s pg_hint_plan extension, MySQL’s built-in Query Rewrite Plugin, and MariaDB MaxScale’s query rewrite filter.
Why Query Rewrite Matters
When a database’s query optimizer produces a poor execution plan, the traditional fixes are:
- Rewrite the application SQL — requires code changes, testing, and deployment
- Add optimizer hints — couples hints to application code
- Use a query rewrite layer — intercept and modify queries transparently at the database or proxy level
Query rewrite tools solve the problem at the infrastructure level. You can redirect a poorly performing query to an optimized version, force specific index usage, or add missing WHERE clauses — all without touching application code.
PostgreSQL: pg_hint_plan
pg_hint_plan is a PostgreSQL extension that allows you to specify optimizer hints using special comments in SQL queries. It overrides the planner’s decisions for specific queries.
Installation
| |
Configuration
| |
Usage Examples
| |
pg_hint_plan Docker Compose
| |
| |
MySQL Query Rewrite Plugin
MySQL 5.7+ includes a built-in Query Rewrite Plugin that allows you to replace incoming queries with rewritten versions based on pattern matching.
Installation
| |
Usage
| |
Advanced Pattern Matching
| |
MySQL Query Rewrite Docker Compose
| |
MariaDB MaxScale Query Rewrite
MaxScale is MariaDB’s database proxy that includes a powerful query rewrite and filter module. It operates at the proxy level, making it database-agnostic.
MaxScale Configuration
| |
Rewrite Rules JSON
| |
MaxScale Docker Compose
| |
Comparison: Query Rewrite Tools
| Feature | pg_hint_plan (PostgreSQL) | MySQL Query Rewrite Plugin | MaxScale Query Rewrite |
|---|---|---|---|
| Database | PostgreSQL only | MySQL 5.7+ | MariaDB/MySQL/PostgreSQL |
| Method | SQL comment hints | Pattern-based replacement | Proxy-level rewriting |
| No App Changes | Partial (needs hints in SQL) | Yes (transparent) | Yes (transparent) |
| Rule Storage | In SQL comments | MySQL table | JSON file |
| Hot Reloading | Yes (per-query) | Yes (flush_rewrite_rules()) | Yes (maxctrl) |
| Pattern Matching | N/A (exact query) | Wildcard with ? params | Named variables (:var) |
| Performance Impact | Minimal (planner override) | Low (pattern match per query) | Low (proxy overhead) |
| Debug Logging | Yes (debug_print) | Yes (rewritten column) | Yes (log files) |
| Docker Support | Community images | Official MySQL image | Official MaxScale image |
| License | PostgreSQL License | GPL v2 | BSL (MariaDB) |
Choosing the Right Query Rewrite Tool
For PostgreSQL users, pg_hint_plan is the go-to solution. It provides fine-grained control over the query planner, allowing you to force specific join methods, index usage, and scan types. The main limitation is that hints must be embedded in the SQL as comments, which may require application code changes or a query-intercepting proxy.
For MySQL users, the built-in Query Rewrite Plugin is the simplest option. Pattern-based rules can redirect or modify any incoming query without application changes. The ? wildcard matching makes it easy to handle parameterized queries.
For mixed-database environments, MaxScale provides the most flexibility. As a database proxy, it can rewrite queries for any backend database type. The named variable system (:var) is more expressive than MySQL’s positional ? parameters.
Why Self-Host Query Rewrite?
Immediate performance gains. A single poorly optimized query can cascade into system-wide slowdowns. Query rewrite tools let you fix performance issues immediately by intercepting and optimizing problematic queries, without waiting for application deployment cycles.
Zero-downtime optimization. When a query plan regression occurs after a database upgrade, query rewrite provides an immediate rollback mechanism. You can redirect the affected queries back to their previous execution paths while investigating the root cause.
Centralized query management. Instead of scattering optimizer hints across dozens of application services, a query rewrite layer keeps all optimization rules in one place. This makes it easier to audit, version-control, and manage query performance policies.
Testing and debugging. Query rewrite tools allow you to experiment with different execution plans in production without modifying application code. You can force specific indexes, change join orders, or add covering index hints to measure the performance impact before making permanent changes.
For related reading, see our database monitoring guide, PostgreSQL high availability, and connection pooler comparison.
FAQ
Does pg_hint_plan work with prepared statements?
Yes, pg_hint_plan works with prepared statements in PostgreSQL. The hint comment must appear at the beginning of the SQL text passed to PREPARE or EXECUTE. For JDBC prepared statements, the hint is included in the original SQL string before parameter substitution.
Can MySQL Query Rewrite handle complex multi-table JOIN queries?
Yes, but pattern matching becomes more complex. The ? wildcard matches any single token, so you need to construct the pattern to match the exact structure of the query. For very complex queries, consider using MaxScale’s named variable approach which is more flexible.
Is there a performance penalty for using query rewrite?
The overhead is minimal. pg_hint_plan adds negligible cost since hints are parsed during the planning phase. MySQL’s Query Rewrite Plugin performs pattern matching on each incoming query, adding approximately 0.1-0.5ms per query depending on the number of active rules. MaxScale adds proxy-level latency of about 0.2ms.
How do I audit which queries were rewritten?
For pg_hint_plan, enable pg_hint_plan.debug_print = 'on' to log hint application in PostgreSQL logs. For MySQL Query Rewrite, the rewritten column in query_rewrite.rewrite_rules shows how many times each rule matched. For MaxScale, enable query logging in the service configuration to capture rewritten queries.
Can query rewrite fix missing index problems?
Query rewrite cannot create indexes, but it can work around missing indexes by forcing the optimizer to use alternative access paths. pg_hint_plan can force index scans even on suboptimal indexes, and MySQL’s Query Rewrite Plugin can inject USE INDEX hints into the rewritten SQL. The proper fix is still to add the correct index.
Does MaxScale Query Rewrite work with PostgreSQL backends?
Yes, MaxScale supports PostgreSQL backends through its PostgreSQL protocol module. The query rewrite filter works at the proxy level, independent of the backend protocol. This makes MaxScale the only tool in this comparison that can rewrite queries for both MySQL and PostgreSQL.