237 lines
8.4 KiB
MySQL
237 lines
8.4 KiB
MySQL
|
|
-- ================================================
|
|||
|
|
-- 完整的数据库优化脚本
|
|||
|
|
-- ================================================
|
|||
|
|
-- 功能:
|
|||
|
|
-- 1. 删除冗余索引(提升写入速度)
|
|||
|
|
-- 2. 创建必要索引(提升查询速度)
|
|||
|
|
-- 3. 分析表(更新统计信息)
|
|||
|
|
-- 4. 验证优化结果
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
USE study;
|
|||
|
|
|
|||
|
|
SELECT '========================================' AS '';
|
|||
|
|
SELECT '开始执行数据库优化' AS '';
|
|||
|
|
SELECT '========================================' AS '';
|
|||
|
|
|
|||
|
|
-- ================================================
|
|||
|
|
-- 第一步:删除冗余索引
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '【第1步】删除冗余索引...' AS '';
|
|||
|
|
|
|||
|
|
-- 检查 student_class.idx_student_id 是否存在
|
|||
|
|
SELECT CASE
|
|||
|
|
WHEN COUNT(*) > 0 THEN '发现冗余索引 idx_student_id,准备删除...'
|
|||
|
|
ELSE '✅ idx_student_id 不存在,无需删除'
|
|||
|
|
END AS status
|
|||
|
|
FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study'
|
|||
|
|
AND TABLE_NAME = 'student_class'
|
|||
|
|
AND INDEX_NAME = 'idx_student_id';
|
|||
|
|
|
|||
|
|
-- 删除 student_class.idx_student_id(如果存在)
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'student_class'
|
|||
|
|
AND INDEX_NAME = 'idx_student_id') > 0,
|
|||
|
|
'ALTER TABLE student_class DROP INDEX idx_student_id',
|
|||
|
|
'SELECT "idx_student_id 不存在" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
SELECT '✅ 冗余索引删除完成' AS result;
|
|||
|
|
|
|||
|
|
-- ================================================
|
|||
|
|
-- 第二步:创建必要的索引
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '【第2步】创建必要的索引...' AS '';
|
|||
|
|
|
|||
|
|
-- 2.1 sys_user_role.idx_user_id
|
|||
|
|
SELECT '正在检查 sys_user_role.idx_user_id...' AS '';
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user_role'
|
|||
|
|
AND INDEX_NAME = 'idx_user_id') = 0,
|
|||
|
|
'ALTER TABLE sys_user_role ADD INDEX idx_user_id (user_id)',
|
|||
|
|
'SELECT "idx_user_id 已存在,跳过" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
-- 2.2 sys_user_role.idx_role_id
|
|||
|
|
SELECT '正在检查 sys_user_role.idx_role_id...' AS '';
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user_role'
|
|||
|
|
AND INDEX_NAME = 'idx_role_id') = 0,
|
|||
|
|
'ALTER TABLE sys_user_role ADD INDEX idx_role_id (role_id)',
|
|||
|
|
'SELECT "idx_role_id 已存在,跳过" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
-- 2.3 sys_role.idx_del_flag
|
|||
|
|
SELECT '正在检查 sys_role.idx_del_flag...' AS '';
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_role'
|
|||
|
|
AND INDEX_NAME = 'idx_del_flag') = 0,
|
|||
|
|
'ALTER TABLE sys_role ADD INDEX idx_del_flag (del_flag)',
|
|||
|
|
'SELECT "idx_del_flag 已存在,跳过" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
-- 2.4 courseware.idx_course_id
|
|||
|
|
SELECT '正在检查 courseware.idx_course_id...' AS '';
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'courseware'
|
|||
|
|
AND INDEX_NAME = 'idx_course_id') = 0,
|
|||
|
|
'ALTER TABLE courseware ADD INDEX idx_course_id (course_id)',
|
|||
|
|
'SELECT "idx_course_id 已存在,跳过" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
-- 2.5 learning_detail.idx_student_course
|
|||
|
|
SELECT '正在检查 learning_detail.idx_student_course...' AS '';
|
|||
|
|
SET @sql = (SELECT IF(
|
|||
|
|
(SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'learning_detail'
|
|||
|
|
AND INDEX_NAME = 'idx_student_course') = 0,
|
|||
|
|
'ALTER TABLE learning_detail ADD INDEX idx_student_course (student_id, course_id)',
|
|||
|
|
'SELECT "idx_student_course 已存在,跳过" AS result'
|
|||
|
|
));
|
|||
|
|
PREPARE stmt FROM @sql;
|
|||
|
|
EXECUTE stmt;
|
|||
|
|
DEALLOCATE PREPARE stmt;
|
|||
|
|
|
|||
|
|
SELECT '✅ 索引创建完成' AS result;
|
|||
|
|
|
|||
|
|
-- ================================================
|
|||
|
|
-- 第三步:分析表(更新统计信息)
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '【第3步】分析表,更新统计信息...' AS '';
|
|||
|
|
|
|||
|
|
ANALYZE TABLE sys_user;
|
|||
|
|
ANALYZE TABLE sys_user_role;
|
|||
|
|
ANALYZE TABLE sys_role;
|
|||
|
|
ANALYZE TABLE student_class;
|
|||
|
|
ANALYZE TABLE courseware;
|
|||
|
|
ANALYZE TABLE learning_detail;
|
|||
|
|
|
|||
|
|
SELECT '✅ 表分析完成' AS result;
|
|||
|
|
|
|||
|
|
-- ================================================
|
|||
|
|
-- 第四步:验证优化结果
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '【第4步】验证优化结果...' AS '';
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
|
|||
|
|
-- 4.1 验证 student_class 冗余索引已删除
|
|||
|
|
SELECT '=== student_class 表索引 ===' AS '';
|
|||
|
|
SELECT CASE
|
|||
|
|
WHEN COUNT(*) = 0 THEN '✅ idx_student_id 已成功删除'
|
|||
|
|
ELSE '❌ idx_student_id 仍然存在!'
|
|||
|
|
END AS '冗余索引检查'
|
|||
|
|
FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study'
|
|||
|
|
AND TABLE_NAME = 'student_class'
|
|||
|
|
AND INDEX_NAME = 'idx_student_id';
|
|||
|
|
|
|||
|
|
-- 4.2 验证必要索引已创建
|
|||
|
|
SELECT '=== sys_user_role 表索引 ===' AS '';
|
|||
|
|
SELECT
|
|||
|
|
CASE WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user_role'
|
|||
|
|
AND INDEX_NAME = 'idx_user_id') > 0
|
|||
|
|
THEN '✅' ELSE '❌' END AS 'idx_user_id',
|
|||
|
|
CASE WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user_role'
|
|||
|
|
AND INDEX_NAME = 'idx_role_id') > 0
|
|||
|
|
THEN '✅' ELSE '❌' END AS 'idx_role_id';
|
|||
|
|
|
|||
|
|
SELECT '=== courseware 表索引 ===' AS '';
|
|||
|
|
SELECT
|
|||
|
|
CASE WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'courseware'
|
|||
|
|
AND INDEX_NAME = 'idx_course_id') > 0
|
|||
|
|
THEN '✅' ELSE '❌' END AS 'idx_course_id';
|
|||
|
|
|
|||
|
|
SELECT '=== learning_detail 表索引 ===' AS '';
|
|||
|
|
SELECT
|
|||
|
|
CASE WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
|
|||
|
|
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'learning_detail'
|
|||
|
|
AND INDEX_NAME = 'idx_student_course') > 0
|
|||
|
|
THEN '✅' ELSE '❌' END AS 'idx_student_course';
|
|||
|
|
|
|||
|
|
-- 4.3 测试查询性能
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '=== 查询性能测试 ===' AS '';
|
|||
|
|
|
|||
|
|
-- 测试角色查询
|
|||
|
|
SET @start = NOW(6);
|
|||
|
|
SELECT COUNT(*) INTO @count FROM sys_user_role WHERE user_id = 455;
|
|||
|
|
SET @end = NOW(6);
|
|||
|
|
SELECT
|
|||
|
|
TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 AS '角色查询耗时(ms)',
|
|||
|
|
CASE
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 50 THEN '✅ 性能优秀'
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 100 THEN '⚠️ 性能一般'
|
|||
|
|
ELSE '❌ 性能较差'
|
|||
|
|
END AS '性能评价';
|
|||
|
|
|
|||
|
|
-- 测试课程查询
|
|||
|
|
SET @start = NOW(6);
|
|||
|
|
SELECT COUNT(*) INTO @count FROM courseware WHERE course_id = 6;
|
|||
|
|
SET @end = NOW(6);
|
|||
|
|
SELECT
|
|||
|
|
TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 AS '课程查询耗时(ms)',
|
|||
|
|
CASE
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 50 THEN '✅ 性能优秀'
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 100 THEN '⚠️ 性能一般'
|
|||
|
|
ELSE '❌ 性能较差'
|
|||
|
|
END AS '性能评价';
|
|||
|
|
|
|||
|
|
-- 测试学习详情查询
|
|||
|
|
SET @start = NOW(6);
|
|||
|
|
SELECT COUNT(*) INTO @count FROM learning_detail WHERE student_id = 9999 AND course_id = 6;
|
|||
|
|
SET @end = NOW(6);
|
|||
|
|
SELECT
|
|||
|
|
TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 AS '学习详情查询耗时(ms)',
|
|||
|
|
CASE
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 50 THEN '✅ 性能优秀'
|
|||
|
|
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 100 THEN '⚠️ 性能一般'
|
|||
|
|
ELSE '❌ 性能较差'
|
|||
|
|
END AS '性能评价';
|
|||
|
|
|
|||
|
|
-- ================================================
|
|||
|
|
-- 完成
|
|||
|
|
-- ================================================
|
|||
|
|
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '========================================' AS '';
|
|||
|
|
SELECT '✅ 数据库优化完成!' AS '';
|
|||
|
|
SELECT '========================================' AS '';
|
|||
|
|
SELECT '' AS '';
|
|||
|
|
SELECT '下一步操作:' AS '';
|
|||
|
|
SELECT '1. 如果所有索引都是 ✅ 且查询 <50ms → 重启应用服务' AS '';
|
|||
|
|
SELECT '2. 如果有 ❌ 或查询 >100ms → 请联系管理员检查' AS '';
|
|||
|
|
SELECT '3. 重启服务后测试导入速度,应该提升 5-10 倍' AS '';
|
|||
|
|
SELECT '' AS '';
|