数据库索引批量添加优化跨境商品检索速度脚本
跨境商品数据量动辄几十万行,如果检索字段没有合理索引,每次查询都要全表扫描,响应速度会越来越慢。
手动给每个需要的字段建索引既耗时又容易遗漏,用批量脚本一次性添加是最直接的方法。
本文以 MySQL 5.7 / 8.0 为例,准备一个可以重复运行的索引添加脚本,并说明执行前后的注意事项,让零基础用户也能直接照做。
准备数据库连接信息与权限
你需要先确认三件事:
- 数据库地址、端口、用户名和密码
- 需要建索引的表名(假设为
products,字段包括sku、category_id、brand、item_name) - 当前用户是否有
ALTER或INDEX权限(如果你用 root 则自带,如果是普通用户可以在控制台执行SHOW GRANTS;检查)
如果还不确定有哪些字段适合索引,
可以先执行 DESC products; 或 SHOW CREATE TABLE products; 查看表结构,
通常出现在 WHERE、JOIN、ORDER BY 中的字段都需要建索引。
编写批量添加索引的 SQL 脚本
下面是一个常见的批量添加索引脚本,采用“先检查索引是否存在,不存在则创建”的方式,避免重复执行时报错。
-- 切换到目标数据库
USE your_database_name;
-- 定义需要添加的索引列表
SET @table_name = 'products';
-- 通过存储过程批量执行
DELIMITER //
CREATE PROCEDURE batch_add_indexes()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE idx_name VARCHAR(100);
DECLARE idx_col VARCHAR(200);
DECLARE cur CURSOR FOR
SELECT CONCAT('idx_', column_name) AS index_name, column_name
FROM information_schema.COLUMNS
WHERE table_schema = DATABASE()
AND table_name = @table_name
AND column_name IN ('sku', 'category_id', 'brand', 'item_name');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO idx_name, idx_col;
IF done THEN
LEAVE read_loop;
END IF;
-- 检查索引是否已存在
SET @exists = (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE table_schema = DATABASE()
AND table_name = @table_name
AND index_name = idx_name);
IF @exists = 0 THEN
SET @sql = CONCAT('ALTER TABLE ', @table_name, ' ADD INDEX ', idx_name, '(', idx_col, ')');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT CONCAT('Created index: ', idx_name) AS message;
ELSE
SELECT CONCAT('Index already exists: ', idx_name) AS message;
END IF;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
-- 执行存储过程
CALL batch_add_indexes();
-- 清理(可选)
DROP PROCEDURE IF EXISTS batch_add_indexes;
脚本说明:
- 循环检查
products表中sku、category_id、brand、item_name字段,如果尚未建立对应索引则创建。 - 索引命名格式为
idx_字段名,方便识别。 - 执行完后会逐条打印已创建或已存在的消息。
如果你的数据库支持 CREATE INDEX IF NOT EXISTS(MySQL 8.0 不支持此语法),也可以用更简洁的写法。
上面脚本兼容 MySQL 5.7 和 8.0。
执行脚本并观察结果
- 登录 MySQL:
mysql -u root -p,输入密码。 - 先执行
USE your_database_name;替换成实际数据库名。 - 粘贴上面整个脚本,或者在客户端中运行。
- 执行
SHOW INDEX FROM products;查看新增的索引。
正常能看到一行或多行记录,例如 idx_sku 等 Non_unique 为 0 且 Key_name 为你的索引名。
验证跨境商品检索速度是否提升
建索引前后可以对比同一条查询语句的执行时间:
-- 开启执行时间统计
SET @start = NOW(6);
SELECT COUNT(*) FROM products WHERE sku IN ('A1001','A1002','A1003');
SELECT TIMEDIFF(NOW(6), @start) AS elapsed;
第二次执行时,由于索引缓存,时间可能更短。
更好的办法是 EXPLAIN 查看是否使用了索引:
EXPLAIN SELECT * FROM products WHERE category_id = 10;
若 possible_keys 和 key 列出现你创建的索引名(如 idx_category_id),说明索引生效。
常见错误和注意事项
- 索引不是越多越好:每个索引都会占用磁盘空间,且写入/更新时需要维护。只给高频查询字段加索引,不要全表字段都加。
- 组合索引:如果多个字段经常联合查询(如
WHERE category_id AND brand),应建组合索引,而不是单独建两个单列索引。 - 执行脚本报错“Duplicate key name”:如果已经有同名索引,脚本会跳过,但如果你手动运行了多条一样的
ALTER TABLE,可以先删除重复索引再执行脚本。 - 宝塔面板用户:在宝塔 phpMyAdmin 中可以直接粘贴脚本执行,或者在后台“数据库”菜单里点击“从文件导入”运行。
- 数据量大时:建索引会锁定表(MySQL 5.6 及以上可用在线 DDL,但建议在业务低峰期执行)。
如果你在跨境商品站中遇到搜索速度慢、后台列表加载卡顿,先检查慢查询日志,再用本文的批量脚本快速补齐缺失的索引,通常能立竿见影。
后续可根据实际查询模式微调索引组合。