GaussDB索引失效深度排查:为什么你的索引不工作?
凌晨三点,运维工程师小李被刺耳的告警声惊醒——核心报表系统又出现了超时。他熟练地连接到GaussDB数据库,发现明明已经为关键查询创建了索引,但执行时间依然长达28秒。这已经是本月第三次类似事件,业务部门的不满情绪正在累积。如果你也遇到过这种"索引失灵"的困境,本文将带你深入GaussDB的索引工作机制,揭示那些教科书上不会告诉你的实战陷阱。
1. 索引失效的六大隐形杀手
1.1 统计信息过时导致优化器误判
GaussDB的查询优化器依赖统计信息来评估不同执行计划的成本。当表数据发生重大变化(超过autovacuum_analyze_threshold设置)而未及时更新统计信息时,优化器可能严重低估需要扫描的行数。
sql复制-- 检查表最后一次分析时间
SELECT schemaname, tablename, last_analyze
FROM pg_stat_all_tables
WHERE schemaname NOT LIKE 'pg_%';
-- 手动更新统计信息(以sell_info_full表为例)
ANALYZE VERBOSE sell_info_full;
提示:对于每日增量超过10%的大表,建议在ETL作业完成后手动执行ANALYZE,而非依赖自动统计信息收集。
1.2 隐式类型转换使索引失效
这是最容易被忽视的问题之一。当查询条件中的数据类型与索引列定义不一致时,GaussDB可能无法使用索引:
sql复制-- 创建了如下索引
CREATE INDEX idx_goods_id ON sell_info_full(goods_id); -- goods_id为char(20)
-- 但以下查询无法使用索引(因为'1001'被识别为整数)
SELECT * FROM sell_info_full WHERE goods_id = 1001;
-- 解决方案:保持类型一致
SELECT * FROM sell_info_full WHERE goods_id = '1001';
常见类型陷阱对照表:
| 索引列类型 | 危险查询示例 | 安全写法 |
|---|---|---|
| varchar | WHERE col = 123 | WHERE col = '123' |
| timestamp | WHERE col > '2023-01-01' | WHERE col > '2023-01-01'::timestamp |
| jsonb | WHERE col->>'key' = 100 | WHERE (col->> |
