导入完成后,如何快速重建索引并收集统计信息?
解读
在国内面试场景里,考官问“导入完成后如何快速重建索引并收集统计信息”,并不是想听“跑个 ANALYZE 就行”这种一句话答案,而是考察你是否理解Cloud SQL 托管边界、引擎差异、导入路径对索引/统计信息的影响以及如何在零停机前提下把执行计划拉回最优。
一句话:既要让考官知道你熟悉Cloud SQL 不提供 OS 级 root 权限这一红线,又要展示你能用Google 原生工具 + SQL 层脚本在最短时间内把实例恢复到生产级性能。
知识点
- Cloud SQL 托管红线:无 SUPER、无 FILE、无 ssh,无法直接调用 myisamchk、pg_ctl、sqlservr.exe 等底层命令。
- 导入路径决定索引状态:
- mysqldump 逻辑导入:默认带 DDL,索引随表一起建,但统计信息为空;
- CSV/SQL 直导:若先禁用索引再导数据,导完需重建;
- Database Migration Service (DMS):自动回写主键/唯一索引,但二级索引与统计信息仍需补;
- pg_restore / SQL Server .bacpac:索引定义会恢复,但统计信息不会。
- 重建索引与收集统计信息必须拆成“Cloud SQL 可执行 SQL”或“gcloud 白名单操作”。
- 国内网络:使用Cloud SQL Auth Proxy + VPC-SC可规避跨省 BGP 抖动,保证大批量 ANALYZE 不中断。
- 大实例需限流:利用max_execution_time(MySQL)、statement_timeout(PG)、**Resource Governor(SQL Server)**防止长事务打爆 HA 副本。
答案
分引擎给出可落地、可在面试现场逐条陈述的操作序列,每条都对应白名单 SQL 或 gcloud 命令,绝对不提需要 root 的黑操作。
MySQL 8.0
- 登录后先通过
SHOW TABLES确认导入完整性; - 重建二级索引:
该存储过程是Cloud SQL 内置白名单函数,内部用CALL mysql.sp_rebuild_index('db_name', 'table_name');ALGORITHM=INPLACE避免锁表; - 批量收集统计信息:
若表超过 100 GB,建议按分区并行执行,利用SET SESSION max_execution_time=0; -- 国内大表需关超时 ANALYZE TABLE db_name.table_name;ANALYZE TABLE ... UPDATE HISTOGRAM只采样 1000 桶,5 分钟内可结束; - 验证执行计划:
确认EXPLAIN FORMAT=JSON SELECT ...;rows_examined与cost_info回落到预估值; - 若实例开启并行复制,用
SHOW REPLICA STATUS确认无Seconds_Behind_Master > 0,避免统计信息延迟导致备库选错索引。
PostgreSQL 13+
- 重建所有无效索引:
REINDEX DATABASE CONCURRENTLY db_name;CONCURRENTLY关键字是Cloud SQL 白名单,不锁 DML; - 收集统计信息:
若单表超 200 GB,用并行 analyze:ALTER SYSTEM SET maintenance_work_mem = '2GB'; -- 需重启失效,改用 per-session SET maintenance_work_mem = '2GB'; ANALYZE;
国内 32 vCPU 实例实测3 分钟完成;ALTER TABLE big_table SET (parallel_workers = 8); ANALYZE big_table; - 更新 pg_stat_statements:
防止旧执行计划缓存干扰;SELECT pg_stat_reset(); - 可选:用
google_sql_tool内置的gcloud sql instances export ... --query="SELECT * FROM pg_stat_user_tables WHERE last_analyze is null"生成未收集清单,一键补漏。
SQL Server 2019
- 重建或重组索引:
EXEC sp_msforeachtable 'USE [db_name]; ALTER INDEX ALL ON ? REBUILD WITH (ONLINE=ON, MAXDOP=8)';ONLINE=ON是Cloud SQL for SQL Server 唯一允许的选项; - 更新统计信息:
该存储过程内部按修改行数阈值智能采样,100 GB 库2 分钟完成;EXEC sp_updatestats; - 验证:
若仍有高碎片,可二次SELECT name AS index_name, avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') WHERE avg_fragmentation_in_percent > 10;REORGANIZE; - 国内若开启分布式可用性组,需用
sys.dm_hadr_database_replica_states确认辅助副本已同步统计信息元数据,防止读-only 路由走错计划。
统一收尾(三引擎通用)
- 用
gcloud sql instances patch <instance_id> --database-flags=auto_explain.log_min_duration=1000临时打开慢查询采样,观察 30 分钟无异常后关闭; - 把上述 SQL 脚本存入Cloud Storage 桶,通过
gcloud sql import sql ...做下次演练一键回放,体现基础设施即代码思维。
拓展思考
- 如果业务要求零停机 + 导入期间索引不可用,可先用Cloud SQL 只读实例做逻辑解码(PG)或CDC(SQL Server),在主库导入完成后切换 VIP,再在旧主库做索引重建,实现蓝绿发布;
- 国内金融云常要求两地三中心,可在上海与张家口双区域各建实例,用DMS 连续复制先全量后增量,等 RPO < 5 秒时再执行上述重建与 ANALYZE,把统计信息更新纳入灾备演练 SOP;
- 对超 10 TB 实例,建议把ANALYZE 拆成列级别,利用 pg_statistic_ext 扩展统计信息或 MySQL histogram_persist 表,只更新 WHERE 条件高频列,把 2 小时窗口压到 15 分钟;
- 面试反问环节可主动问考官:“贵司是否已接入Cloud SQL 的 Terraform 模块?我可以把重建索引与收集统计信息封装成null_resource + local-exec,让每次导入自动触发,无需人工值守。”——既展示IaC 能力,又把话题拉回Google Cloud 生态优势,形成技术 + 业务双赢闭环。