guoyu/log/Sql/fix_core_performance.sql

232 lines
7.6 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ================================================
-- 修复核心性能问题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 '';