In day-to-day operations of a gbase database, a query that ran in seconds yesterday might suddenly take minutes today — even with indexes in place. The root cause is often stale statistics that mislead the cost‑based optimizer. This guide covers the essential tools: understanding cardinality, using ANALYZE TABLE, reading EXPLAIN output, and applying Hints when necessary.
The Core Metric: Cardinality
The optimizer relies on statistics like row counts and cardinality (the number of distinct values in a column) to estimate how effective an index will be. High cardinality encourages index use; low cardinality may lead to a full table scan. If statistics are out of date, the optimizer makes poor decisions.
-- Check column statistics
SHOW INDEX FROM orders;
-- Alternatively
SELECT TABLE_NAME, COLUMN_NAME, CARDINALITY
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'orders';
Refreshing Statistics with ANALYZE TABLE
ANALYZE TABLE updates statistics immediately for new query plans. Existing running queries are not affected.
-- Single table
ANALYZE TABLE orders;
-- Multiple tables
ANALYZE TABLE orders, order_items, customers;
Crucially, after adding a new partition, you must run ANALYZE TABLE. Without it, the optimizer underestimates the partition's size, potentially disabling partition pruning and selecting wrong parallelism.
ALTER TABLE sales ADD PARTITION (PARTITION p202406 VALUES LESS THAN ('2024-07-01'));
ANALYZE TABLE sales;
Diagnosing with EXPLAIN
EXPLAIN SELECT * FROM orders WHERE customer_id = 12345;
If type shows ALL, it's a full table scan. Common causes: missing index, outdated statistics (cardinality is zero or too low), implicit type conversion, or using a function on the indexed column.
Solution workflow:
- Check if the index exists (
SHOW INDEX). - Run
ANALYZE TABLE. - Verify with
EXPLAINagain. - If still
ALL, inspect the SQL for type mismatches or functions on the index column.
Hint: Emergency Override
When statistics are correct but the optimizer still picks a bad plan, Hints provide a temporary override. Use them sparingly and document why.
- JOIN order:
SELECT STRAIGHT_JOIN a.*, b.name
FROM large_table a JOIN small_table b ON a.id = b.id;
- Index hints:
SELECT * FROM orders USE INDEX (idx_customer_id) WHERE customer_id = 12345;
SELECT * FROM orders FORCE INDEX (idx_customer_id) WHERE customer_id = 12345;
SELECT * FROM orders IGNORE INDEX (idx_create_time) WHERE customer_id = 12345;
- Parallelism hint (GBase 8a‑specific):
SELECT /*+ PARALLEL(4) */ COUNT(*) FROM large_table;
Always verify with EXPLAIN that the hint is being respected.
Complete Tuning Flow
-
EXPLAINthe slow query. - If
type = ALL: check indexes → if missing, create; if present, runANALYZE TABLE→ re‑evaluate. - If JOIN order is wrong: update statistics → if still bad, apply
STRAIGHT_JOINhint. - If statistics are fine but plan remains poor: use targeted hints, record the reason, and schedule a follow‑up review.
Operational Best Practices
- Run
ANALYZE TABLEimmediately after bulk data loads. - Run
ANALYZE TABLEimmediately after adding partitions. - Schedule a weekly
ANALYZEfor core business tables. - When troubleshooting slow queries, always start with
ANALYZE, thenEXPLAIN. - After version upgrades, perform a full
ANALYZEand re‑validate critical execution plans.
Keeping statistics fresh is the single most reliable way to keep your gbase database performing predictably. Make "ANALYZE after change" a habit, and you will avoid the vast majority of unexpected plan regressions.
Top comments (0)