Project | Requirement |
TencentDB for PostgreSQL version | 15.x or later |
Extension version | tencentdb_index_advisor v1.0 |
Dependent extension | hypopg v1.4.1 (automatically installed) |
Execution permission | Members of the pg_tencentdb_superuser role |
Execution environment | Executable only on the Primary (Primary). |
-- Install the hypopg extension (if it is not already installed).CREATE EXTENSION IF NOT EXISTS hypopg;-- Install the index recommendation extension.CREATE EXTENSION IF NOT EXISTS tencentdb_index_advisor;
SELECT extname, extversion FROM pg_extensionWHERE extname IN ('hypopg', 'tencentdb_index_advisor')ORDER BY extname;
extname | extversion |
hypopg | 1.4.1 |
tencentdb_index_advisor | 1.0 |
tencentdb_index_advise(query_string text)RETURNS TABLE (schema_name text,table_name text,am_name text,index_size bigint,index_def text)
Parameter | Type | Description |
query_string | text | The SQL statement(s) to be analyzed, supporting single or multiple statements (separated by semicolons). |
Field | Type | Description |
schema_name | text | The name of the Schema where the recommended index resides |
table_name | text | The name of the table where the recommended index resides |
am_name | text | Index access method (typically btree) |
index_size | bigint | Estimated index size (in bytes) |
index_def | text | The complete CREATE INDEX statement, which can be executed directly |
Parameter Name | Type | Default Value | Description |
tencentdb_index_advisor.enable_covering_index | bool | on | Whether to enable covering index recommendations. After enabled, recommended indexes include the extra columns required by queries, supporting index-only scan (Index-Only Scan). |
tencentdb_index_advisor.show_benefits | bool | on | Whether to display the estimated cost benefit of recommended indexes |
tencentdb_index_advisor.try_variation_timeout | int | 10 (seconds) | Timeout for the variation optimization phase. Setting it to 0 skips this phase and speeds up recommendation. |
tencentdb_index_advisor.enable_workload_compression | bool | off | Whether to enable workload compression. After enabled, SQL statements with similar patterns are deduplicated to reduce processing time. |
tencentdb_index_advisor.max_index_recommend | int | 8 | Maximum number of indexes recommended per session |
-- Disable covering index recommendations (to reduce index size).SET tencentdb_index_advisor.enable_covering_index = off;-- Limit the maximum number of recommended indexes to 3.SET tencentdb_index_advisor.max_index_recommend = 3;-- Skip the mutation optimization phase (to speed up recommendations).SET tencentdb_index_advisor.try_variation_timeout = 0;-- Enable workload compression during batch analysis.SET tencentdb_index_advisor.enable_workload_compression = on;
-- Recommend indexes for slow queries.SELECT schema_name, table_name, am_name,pg_size_pretty(index_size) AS est_size,index_defFROM tencentdb_index_advise('SELECT * FROM orders WHERE customer_id = 123 AND status = ''shipped'' AND order_date > ''2025-01-01''');
schema_name | table_name | am_name | est_size | index_def |
public | orders | btree | 2360 kB | CREATE INDEX ON public.orders USING btree (customer_id,status) |
SELECT schema_name, table_name, am_name,pg_size_pretty(index_size) AS est_size,index_defFROM tencentdb_index_advise('SELECT o.id, c.name, o.amountFROM orders o JOIN customers c ON o.customer_id = c.idWHERE c.city = ''Beijing'' AND o.status = ''delivered''');
schema_name | table_name | am_name | est_size | index_def |
public | orders | btree | 4528 KB | CREATE INDEX ON public.orders USING btree (status,customer_id,id,amount) |
public | customers | btree | 312 KB | CREATE INDEX ON public.customers USING btree (city) |
-- Analyze multiple business SQL statements simultaneously.SELECT schema_name, table_name,pg_size_pretty(index_size) AS est_size,index_defFROM tencentdb_index_advise('SELECT * FROM orders WHERE customer_id = 100;SELECT * FROM orders WHERE status = ''pending'' AND region = ''east'';SELECT * FROM products WHERE category = ''electronics'' AND price < 200;SELECT o.id, c.name FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.city = ''Beijing'';');
schema_name | table_name | est_size | index_def |
public | orders | 8350 KB | CREATE INDEX ON public.orders USING btree (customer_id,...) |
public | orders | 8350 KB | CREATE INDEX ON public.orders USING btree (region,status,...) |
public | products | 1416 KB | CREATE INDEX ON public.products USING btree (category,price,...) |
public | customers | 312 KB | CREATE INDEX ON public.customers USING btree (city,...) |
-- Enable covering index recommendations.SET tencentdb_index_advisor.enable_covering_index = on;SELECT index_def FROM tencentdb_index_advise('SELECT customer_id, amount FROM orders WHERE status = ''shipped'' AND region = ''east''');-- Result: CREATE INDEX ON public.orders USING btree (region, status, customer_id, amount)-- Disable covering index recommendations.SET tencentdb_index_advisor.enable_covering_index = off;SELECT index_def FROM tencentdb_index_advise('SELECT customer_id, amount FROM orders WHERE status = ''shipped'' AND region = ''east''');-- Result: CREATE INDEX ON public.orders USING btree (region, status)
-- Index Recommendations for UPDATE StatementsSELECT index_def FROM tencentdb_index_advise('UPDATE orders SET amount = 0 WHERE customer_id = 123 AND status = ''cancelled''');-- Result: CREATE INDEX ON public.orders USING btree (customer_id, status)-- Index Recommendations for DELETE StatementsSELECT index_def FROM tencentdb_index_advise('DELETE FROM orders WHERE customer_id = 999 AND order_date < ''2025-01-01''');-- Result: CREATE INDEX ON public.orders USING btree (customer_id, order_date)
Input the SQL statement.│▼Step 1: Query Parsing└── Parse clauses such as WHERE/JOIN/GROUP BY/ORDER BY.│Step 2: Candidate Index Column Generation└── Identify candidate columns by priority:EQUALITY (equality) > RANGE (range) > JOIN (join)> GROUP_ORDER (sorting/grouping) > COVERING (covering)│Step 3: Hypothetical Index Creation└── Create a hypothetical index using hypopg (does not occupy disk space).│Step 4: Cost Evaluation└── Use the PostgreSQL optimizer to evaluate the execution cost difference with and without an index.│Step 5: Greedy Selection + Mutation Optimization└── Use a greedy algorithm to select the index combination with the greatest benefit.During the mutation phase, different combinations are attempted to find a better solution.│Step 6: Output Recommendations└── Return the CREATE INDEX statement and the estimated index size.
Priority | Type | Scenario | Description |
1 (Highest) | EQUALITY | WHERE col = value | Equality matching with the best selectivity |
2 | RANGE | WHERE col > value | Range query |
3 | JOIN | ON a.col = b.col | Join condition |
4 | GROUP_ORDER | GROUP BY col / ORDER BY col | Sorting and Grouping |
5 (Lowest) | COVERING | SELECT col | Covering query columns (to avoid table lookups) |
Step 1: Extract the TOP slow queries from pg_stat_statements.└── SELECT query FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;│Step 2: Batch Input to Index Recommendation└── SELECT * FROM tencentdb_index_advise('slow_query1; slow_query2; ...');│Step 3: Evaluate Recommended Indexes├── Check the estimated index size to assess its impact on disk space.├── Use EXPLAIN to verify changes in the query plan.└── Confirm that there are no duplicate/redundant indexes.│Step 4: Create Indexes During Off-Peak Hours└── CREATE INDEX CONCURRENTLY ... (Creates the index online without locking the table.)│Step 5: Verify the Results└── Compare query execution times and execution plans before and after creation.
-- Step 1: View the current execution plan and cost.EXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND status = 'shipped';-- Result: Seq Scan, cost=1218.0-- Step 2: Obtain the Recommended IndexSELECT index_def FROM tencentdb_index_advise('SELECT * FROM orders WHERE customer_id = 123 AND status = ''shipped''');-- Result: CREATE INDEX ON public.orders USING btree (customer_id, status)-- Step 3: Create the index (Use CONCURRENTLY in production environments.)CREATE INDEX CONCURRENTLY idx_orders_cust_statusON orders USING btree (customer_id, status);-- Step 4: Verify the Optimization ResultsEXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND status = 'shipped';-- Result: Index Scan, cost=8.31 (99.3% performance improvement)
Scenario | Recommended Parameter Setting | Description |
Quick Recommendation | try_variation_timeout = 0 | Skips variation optimization, suitable for emergency troubleshooting. |
Deep Optimization | try_variation_timeout = 30 | Performing more thorough combinatorial searches, suitable for important queries. |
Controlling Index Quantity | max_index_recommend = 3 | Limits the number of recommendations to avoid excessive indexes. |
Reducing Index Size | enable_covering_index = off | Does not recommend covering columns, resulting in smaller indexes. |
Batch Analysis | enable_workload_compression = on | Deduplicates similar SQL statements to accelerate analysis speed. |
Term | Description |
Hypothetical Index | A virtual index created through the hypopg extension, which resides only in session memory, does not occupy disk space, but can be recognized and used by the PostgreSQL optimizer for execution plan evaluation. |
Covering Index (Covering Index) | An index that contains all columns required by a query, supports index-only scan (Index-Only Scan), and avoids reading data pages by returning to the table. |
Variation Phase | The optimization phase that, after the greedy algorithm yields a preliminary result, seeks a better solution by trying different index column combinations. |
Workload Compression | Performs pattern matching and deduplication on input SQL statements, preserving query diversity while reducing analysis time. |
RMGR | Resource Manager, a type of resource manager. |
Index-Only Scan | Index-only scan, where a query can obtain all required data by reading only the index, without needing to access heap pages by returning to the table. |
CONCURRENTLY | PostgreSQL's online index creation mode, which does not block DML operations on the table. |
Was this page helpful?
You can also Contact sales or Submit a Ticket for help.
Help us improve! Rate your documentation experience in 5 mins.
Feedback