--- title: The online_advisor extension subtitle: Get index, statistics, and prepared statement recommendations based on your query workload enableTableOfContents: true updatedOn: '2025-08-16T11:33:02.132Z' --- The `online_advisor` extension recommends **indexes**, **extended statistics**, and **prepared statements** based on your actual query workload. It uses the same executor hook mechanism as [`auto_explain`](https://www.postgresql.org/docs/current/auto-explain.html) to collect and analyze execution data. ## What it does - Suggests **indexes** when queries filter many rows - Suggests **extended statistics** when the planner's row estimates are far off from actuals - Identifies queries that could benefit from **prepared statements** when planning time is high `online_advisor` only makes recommendations. It does not create indexes or statistics for you. ## Requirements - Supported on Postgres **17** - Create the extension in every database you want to inspect - Activate it by calling any provided function (for example, `get_executor_stats()`) ### Version availability Please refer to the [Supported Postgres extensions](/docs/extensions/pg-extensions) page for the latest supported version of `online_advisor` on Neon. ## Enable the online_advisor extension You can create the extension in each target database using `CREATE EXTENSION`: ```sql CREATE EXTENSION online_advisor; ``` For information about using the Neon SQL Editor, see [Query with Neon's SQL Editor](/docs/get-started/query-with-neon-sql-editor). For information about using the `psql` client with Neon, see [Connect with psql](/docs/connect/query-with-psql-editor). ## Start collecting recommendations 1. Activate the extension by calling any function: ```sql SELECT get_executor_stats(); ``` 2. Run your workload to collect data. 3. View recommendations: ```sql -- Proposed indexes SELECT * FROM proposed_indexes ORDER BY elapsed_sec DESC; -- Proposed extended statistics SELECT * FROM proposed_statistics ORDER BY elapsed_sec DESC; ``` ## Apply accepted recommendations Run the `create_index` or `create_statistics` statement from the views, then analyze the table: ```sql CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_orders_customer_date ON orders(customer_id, order_date); VACUUM (ANALYZE) orders; ``` ## Configure thresholds You can tune `online_advisor` with these settings: | Setting | Default | Description | | ---------------------------------------- | ------- | ---------------------------------------------------------------------------------------- | | `online_advisor.filtered_threshold` | `1000` | Minimum filtered rows in a node to suggest an index. | | `online_advisor.misestimation_threshold` | `10` | Minimum actual/estimated row ratio to flag misestimation. | | `online_advisor.min_rows` | `1000` | Minimum returned rows before misestimation is considered. | | `online_advisor.max_index_proposals` | `1000` | Max tracked clauses for index proposals (system-level, read-only on Neon). | | `online_advisor.max_stat_proposals` | `1000` | Max tracked clauses for extended statistics proposals (system-level, read-only on Neon). | | `online_advisor.do_instrumentation` | `on` | Toggle data collection. | | `online_advisor.log_duration` | `off` | Log planning/execution time for each query. | | `online_advisor.prepare_threshold` | `1.0` | Planning/execution time ratio above which to suggest prepared statements. | On Neon, you can only modify session-level settings using `SET`. System-level settings like `online_advisor.max_index_proposals` and `online_advisor.max_stat_proposals` use default values and cannot be changed. If you need different system-level settings, reach out to Neon Support. Change a setting for the current session: ```sql SET online_advisor.filtered_threshold = 2000; ``` ## Check planning and execution stats Use `get_executor_stats()` to see planning and execution times and whether prepared statements might help: ```sql SELECT * FROM get_executor_stats(false); -- false = do not reset counters ``` Look at `avg_planning_overhead`. Values greater than `1` suggest that some queries would benefit from prepared statements. ## Combine or separate index proposals By default, `online_advisor` tries to combine related predicates into a single compound index. To view separate recommendations for each predicate: ```sql SELECT * FROM propose_indexes(false); ``` ## Limitations - Does not check operator ordering for compound indexes - Does not suggest indexes for joins or `ORDER BY` clauses - Does not estimate the benefit of adding an index — pair with [HypoPG](https://github.com/HypoPG/hypopg#) if you want to simulate usage - Recommendations are per database ## Remove the extension ```sql DROP EXTENSION IF EXISTS online_advisor; ``` If you're not using it anywhere, remove it from `shared_preload_libraries` and restart. ## Example workflow ```sql -- Activate and run workload SELECT get_executor_stats(); -- View index proposals SELECT create_index, n_filtered, n_called, elapsed_sec FROM proposed_indexes ORDER BY elapsed_sec DESC LIMIT 10; -- View extended statistics proposals SELECT create_statistics, misestimation, n_called, elapsed_sec FROM proposed_statistics ORDER BY misestimation DESC LIMIT 10; -- Apply a recommendation CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_orders_customer_date ON orders(customer_id, order_date); VACUUM (ANALYZE) orders; -- Check planning/execution times SELECT * FROM get_executor_stats(true); -- reset after reading ``` ## Resources - [online_advisor GitHub repository](https://github.com/knizhnik/online_advisor) - [PostgreSQL auto_explain documentation](https://www.postgresql.org/docs/current/auto-explain.html)