CONCEPT Cited by 1 source
SET_VAR optimizer hint¶
Definition¶
SET_VAR is a MySQL 8.0 optimizer hint that applies a session system variable for the duration of a single query without modifying the underlying connection state. The hint is written in SQL comment syntax: /*+ SET_VAR(var_name = value) */, placed immediately after the SELECT / INSERT / UPDATE / DELETE keyword.
Example (from sources/2026-04-21-planetscale-connection-pooling-in-vitess):
-- Before: tainting SET, then a query
SET unique_checks = 0;
INSERT INTO user (id, name) VALUES (1, 'foo');
-- After: equivalent single-query with SET_VAR hint
INSERT /*+ SET_VAR(unique_checks=0) */ INTO user (id, name) VALUES (1, 'foo');
Both forms produce the same result (unique_checks=0 is in effect while the INSERT runs) but with different connection-state consequences: the SET form taints the connection for all subsequent queries on it, while the SET_VAR form affects only the single query and leaves connection state untouched.
Why it matters to connection pooling¶
SET_VAR is the per-query escape hatch that lets a pooled connection serve a caller who needs non-default session settings without becoming a tainted connection. Because the setting scope is one query, the connection is fungible again as soon as the query completes — no restore needed, no close needed, no reservation needed.
In Vitess (Era 2, v7.0–v14): when a client issues a SET statement, the proxy does not taint the connection. Instead, it records the setting on the session and rewrites every subsequent query in that session to carry the setting as a SET_VAR hint (Source: sources/2026-04-21-planetscale-connection-pooling-in-vitess):
"Building on the previous example, once Vitess recognizes that the
unique_checkssetting is being altered, all subsequent queries within that session are rewritten. For example, the queryinsert into user (id, name) values (1, 'foo')will be rewritten asinsert /*+ SET_VAR(unique_checks=0) */ into user (id, name) values (1, 'foo')."
This lets Vitess keep the connection in the shared pool across the caller's session — pool benefits preserved, ORM-compatibility preserved.
Eligibility constraint¶
Not every system variable can be set via SET_VAR. MySQL's Server System Variables reference marks eligibility per variable. Broadly eligible families:
- Optimizer-behaviour variables (
optimizer_switch,optimizer_trace,optimizer_search_depth). - Query-execution variables (
unique_checks,foreign_key_checks,sql_mode,max_execution_time). - Join/sort tuning (
sort_buffer_size,join_buffer_size).
Broadly ineligible families:
- Variables that affect the session's protocol/encoding state (
character_set_client,character_set_results,collation_connection— changing these mid-query would require renegotiation). - Variables that affect transaction semantics across statements (
autocommit, some aspects oftransaction_isolation). - Variables that affect session resources (
max_user_connections, user-defined variables@x).
"it's essential to note that not all settings can be used with SET_VAR. For those that are not permitted, reserved connections must still be used." — Harshit Gangal, sources/2026-04-21-planetscale-connection-pooling-in-vitess
This means SET_VAR is a partial mitigation, not a complete replacement for connection taint handling. In Vitess's design trajectory, it is one of two pre-v15 mitigations (alongside no-op elision) and remains load-bearing in v15+ alongside the settings pool for settings that are SET_VAR-eligible.
Relationship to the settings pool¶
| Mechanism | Setting scope | Connection state | Pool ceiling |
|---|---|---|---|
SET var = value |
Session | Tainted | Every taint forces reservation |
SET_VAR(var=value) |
Single query | Untouched | Preserved (for eligible vars only) |
| Settings pool (v15) | Session | Tainted, but pool manages it | Preserved (all vars, with bookkeeping cost) |
The three mechanisms compose. Vitess's current architecture applies SET_VAR for eligible variables (cheaper — no pool bookkeeping) and falls back to the settings pool for ineligible ones (slightly more expensive but covers the full surface).
Historical note¶
SET_VAR was added in MySQL 8.0.3 (2017). Before MySQL 8.0, the only way to apply a session variable per-query was either (a) SET + query + SET back (two extra round trips), which is incompatible with pooling anyway, or (b) reserve the connection for the whole session. SET_VAR is one of the MySQL 8.0 features Vitess specifically leans on for its v7.0+ pool-compatible-ORM story — another MySQL-8-specific primitive whose availability shapes Vitess's design surface.
Seen in¶
- sources/2026-04-21-planetscale-connection-pooling-in-vitess — canonical first wiki citation. Gangal walks through Vitess's pre-v15 query-rewriting mechanism that substitutes
SET_VARhints for client-issuedSETstatements, keeping connections pool-eligible. The "not all settings can be used with SET_VAR" caveat is canonicalised here as the load-bearing reason why settings-pool (v15) still needed to be built even after SET_VAR rewriting shipped.
Related¶
- concepts/tainted-connection — the problem
SET_VARsidesteps. - concepts/reserved-connection — the fallback when
SET_VARis not applicable. - concepts/session-level-system-setting — the variable family
SET_VARaddresses. - patterns/settings-aware-connection-pool — the complementary mechanism for SET_VAR-ineligible variables.
- systems/mysql — MySQL 8.0 is the minimum version for this hint.
- systems/vitess — canonical consumer of
SET_VARfor pool preservation.