guoyu/log/Sql/fix_core_performance.sql

232 lines
7.6 KiB
MySQL
Raw Normal View History

-- ================================================
-- 修复核心性能问题UPDATE 和 SELECT 慢)
-- ================================================
-- 问题:
-- 1. UPDATE sys_user WHERE user_id = ? 慢1144ms
-- 2. SELECT FROM student_class WHERE student_id = ? 慢573ms
-- 3. SELECT FROM sys_user (JOIN 查询) 慢575ms
-- ================================================
USE study;
SELECT '========================================' AS '';
SELECT '修复核心性能问题' AS '';
SELECT '========================================' AS '';
-- ================================================
-- 1. 检查 sys_user 表结构和索引
-- ================================================
SELECT '' AS '';
SELECT '【检查1】sys_user 表索引' AS '';
SHOW INDEX FROM sys_user;
-- 检查 user_id 是否是主键
SELECT CASE
WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user'
AND INDEX_NAME = 'PRIMARY' AND COLUMN_NAME = 'user_id') > 0
THEN '✅ user_id 是主键'
ELSE '❌ user_id 不是主键!'
END AS 'user_id 主键检查';
-- 检查 user_name 索引(用于查询是否存在)
SELECT CASE
WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user'
AND COLUMN_NAME = 'user_name') > 0
THEN '✅ user_name 有索引'
ELSE '❌ user_name 无索引'
END AS 'user_name 索引检查';
-- ================================================
-- 2. 检查 student_class 表索引
-- ================================================
SELECT '' AS '';
SELECT '【检查2】student_class 表索引' AS '';
SHOW INDEX FROM student_class;
-- ================================================
-- 3. 检查表的数据量和碎片
-- ================================================
SELECT '' AS '';
SELECT '【检查3】表数据量和碎片' AS '';
SELECT
TABLE_NAME AS '表名',
TABLE_ROWS AS '行数',
ROUND(DATA_LENGTH/1024/1024, 2) AS '数据大小(MB)',
ROUND(INDEX_LENGTH/1024/1024, 2) AS '索引大小(MB)',
ROUND(DATA_FREE/1024/1024, 2) AS '碎片大小(MB)',
CASE
WHEN DATA_FREE > 0 THEN '⚠️ 有碎片'
ELSE '✅ 无碎片'
END AS '碎片状态'
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'study'
AND TABLE_NAME IN ('sys_user', 'student_class', 'sys_user_role', 'sys_dept', 'sys_role')
ORDER BY TABLE_ROWS DESC;
-- ================================================
-- 4. 优化表(清理碎片)
-- ================================================
SELECT '' AS '';
SELECT '【优化1】清理表碎片...' AS '';
OPTIMIZE TABLE sys_user;
OPTIMIZE TABLE student_class;
OPTIMIZE TABLE sys_user_role;
SELECT '✅ 表优化完成' AS result;
-- ================================================
-- 5. 创建必要的复合索引
-- ================================================
SELECT '' AS '';
SELECT '【优化2】创建复合索引...' AS '';
-- sys_user 表dept_id 索引(用于 JOIN
SELECT '正在检查 sys_user.idx_dept_id...' AS '';
SET @sql = (SELECT IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user'
AND INDEX_NAME = 'idx_dept_id' AND COLUMN_NAME = 'dept_id') = 0,
'ALTER TABLE sys_user ADD INDEX idx_dept_id (dept_id)',
'SELECT "idx_dept_id 已存在,跳过" AS result'
));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- sys_user 表del_flag 索引(用于 WHERE u.del_flag = '0'
SELECT '正在检查 sys_user.idx_del_flag...' AS '';
SET @sql = (SELECT IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_user'
AND INDEX_NAME = 'idx_del_flag' AND COLUMN_NAME = 'del_flag') = 0,
'ALTER TABLE sys_user ADD INDEX idx_del_flag (del_flag)',
'SELECT "idx_del_flag 已存在,跳过" AS result'
));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- sys_dept 表dept_id 主键应该已存在,检查一下
SELECT '正在检查 sys_dept 索引...' AS '';
SELECT CASE
WHEN (SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'study' AND TABLE_NAME = 'sys_dept'
AND INDEX_NAME = 'PRIMARY' AND COLUMN_NAME = 'dept_id') > 0
THEN '✅ sys_dept.dept_id 是主键'
ELSE '⚠️ sys_dept.dept_id 不是主键'
END AS result;
SELECT '✅ 索引创建完成' AS result;
-- ================================================
-- 6. 重新分析表
-- ================================================
SELECT '' AS '';
SELECT '【优化3】重新分析表...' AS '';
ANALYZE TABLE sys_user;
ANALYZE TABLE student_class;
ANALYZE TABLE sys_user_role;
ANALYZE TABLE sys_dept;
ANALYZE TABLE sys_role;
SELECT '✅ 表分析完成' AS result;
-- ================================================
-- 7. 测试查询性能
-- ================================================
SELECT '' AS '';
SELECT '【测试】查询性能测试' AS '';
-- 测试 UPDATE实际是测试 WHERE user_id = ?
SET @start = NOW(6);
SELECT * FROM sys_user WHERE user_id = 207 AND del_flag = '0';
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 < 200 THEN '⚠️ 一般'
ELSE '❌ 较差'
END AS '性能';
-- 测试 student_class 查询
SET @start = NOW(6);
SELECT * FROM student_class WHERE student_id = 207 ORDER BY join_time DESC;
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 < 200 THEN '⚠️ 一般'
ELSE '❌ 较差'
END AS '性能';
-- 测试复杂 JOIN 查询
SET @start = NOW(6);
SELECT u.user_id, u.user_name, d.dept_name, r.role_name
FROM sys_user u
LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
LEFT JOIN sys_role r ON r.role_id = ur.role_id
WHERE u.user_id = 207 AND u.del_flag = '0';
SET @end = NOW(6);
SELECT
TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 AS 'JOIN查询耗时(ms)',
CASE
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 100 THEN '✅ 优秀'
WHEN TIMESTAMPDIFF(MICROSECOND, @start, @end)/1000 < 300 THEN '⚠️ 一般'
ELSE '❌ 较差'
END AS '性能';
-- ================================================
-- 8. 检查是否有锁表或慢查询
-- ================================================
SELECT '' AS '';
SELECT '【诊断】检查锁表和慢查询' AS '';
-- 检查当前运行的查询
SELECT
ID AS '进程ID',
USER AS '用户',
HOST AS '主机',
DB AS '数据库',
COMMAND AS '命令',
TIME AS '耗时(秒)',
STATE AS '状态',
LEFT(INFO, 50) AS 'SQL前50字符'
FROM information_schema.PROCESSLIST
WHERE COMMAND != 'Sleep'
AND TIME > 1
ORDER BY TIME DESC
LIMIT 10;
-- ================================================
-- 完成
-- ================================================
SELECT '' AS '';
SELECT '========================================' AS '';
SELECT '✅ 核心性能优化完成!' AS '';
SELECT '========================================' AS '';
SELECT '' AS '';
SELECT '下一步:' AS '';
SELECT '1. 重启应用服务' AS '';
SELECT '2. 测试导入10条数据' AS '';
SELECT '3. 如果仍然慢UPDATE >500ms可能是网络问题' AS '';
SELECT '' AS '';