已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
我们有一个多租户的数据库系统,核心表 t_invoice_item 有 2.3 亿行数据,每天凌晨 2 点到 5 点执行批处理任务,将大量数据从状态 UNBILLED 灌入到已处理状态。批处理任务结束后,执行 ANALYZE TABLE t_invoice_item 来刷新统计信息。
在白天,执行查询 SELECT id, amount, status FROM t_invoice_item WHERE tenant_id = ? AND billing_period = ? AND status = 'UNBILLED' ORDER BY id LIMIT 500; 时,查询会走 idx_tenant_period 索引,执行时间在 5ms 以内。但在凌晨批跑任务结束后,执行相同 SQL 时,会突变为全表扫描,执行时间飙升至 120ms,甚至更高。
ANALYZE TABLE t_invoice_item 后,查询会立即走索引,但 2–4 小时后(通常在批跑窗口附近)再次漂移。UNBILLED 占比从白天的 12% 掉到凌晨的 3%,这导致优化器选择全表扫描。ANALYZE TABLE,但发现统计信息刷新后,UNBILLED 占比恢复,但执行计划仍可能漂移。EXPLAIN 检查执行计划,发现执行计划确实发生了变化。