12.3 数据库性能优化

面试重要程度:⭐⭐⭐⭐⭐

常见提问方式: "如何优化慢SQL?" "索引设计原则?" "数据库架构如何演进?"

预计阅读时间:45分钟

🔍 SQL性能优化技巧

慢SQL分析与优化

/**
 * SQL性能优化工具类
 */
public class SQLOptimizer {
    
    /**
     * 常见慢SQL类型
     */
    public enum SlowQueryType {
        FULL_TABLE_SCAN("全表扫描", "缺少索引或索引失效"),
        INEFFICIENT_JOIN("低效连接", "连接条件不当或缺少索引"),
        SUBQUERY_OPTIMIZATION("子查询优化", "EXISTS替代IN,JOIN替代子查询"),
        FUNCTION_IN_WHERE("WHERE中使用函数", "导致索引失效"),
        LIKE_PREFIX_WILDCARD("LIKE前缀通配符", "%开头的LIKE查询"),
        ORDER_BY_WITHOUT_INDEX("ORDER BY无索引", "排序字段缺少索引");
        
        private final String name;
        private final String description;
        
        SlowQueryType(String name, String description) {
            this.name = name;
            this.description = description;
        }
    }
    
    /**
     * SQL优化示例
     */
    public static class OptimizationExamples {
        
        public static String optimizeFullTableScan() {
            return """
                -- 原SQL(全表扫描)
                SELECT * FROM orders WHERE status = 'PENDING';
                
                -- 优化后(添加索引)
                CREATE INDEX idx_orders_status ON orders(status);
                SELECT * FROM orders WHERE status = 'PENDING';
                """;
        }
        
        public static String optimizeJoin() {
            return """
                -- 原SQL(低效连接)
                SELECT o.*, u.name 
                FROM orders o, users u 
                WHERE o.user_id = u.id AND o.status = 'PENDING';
                
                -- 优化后(显式JOIN + 索引)
                CREATE INDEX idx_orders_user_status ON orders(user_id, status);
                SELECT o.*, u.name 
                FROM orders o 
                INNER JOIN users u ON o.user_id = u.id 
                WHERE o.status = 'PENDING';
                """;
        }
        
        public static String optimizeSubquery() {
            return """
                -- 原SQL(低效子查询)
                SELECT * FROM users 
                WHERE id IN (SELECT user_id FROM orders WHERE status = 'PENDING');
                
                -- 优化后(EXISTS替代IN)
                SELECT * FROM users u
                WHERE EXISTS (
                    SELECT 1 FROM orders o 
                    WHERE o.user_id = u.id AND o.status = 'PENDING'
                );
                """;
        }
    }
}

📊 索引设计最佳实践

索引策略与优化

/**
 * 索引设计最佳实践
 */
public class IndexDesignBestPractices {
    
    /**
     * 索引类型枚举
     */
    public enum IndexType {
        PRIMARY("主键索引", "唯一且不为空,聚簇索引"),
        UNIQUE("唯一索引", "保证数据唯一性"),
        NORMAL("普通索引", "最常用的索引类型"),
        COMPOSITE("复合索引", "多列组合索引"),
        COVERING("覆盖索引", "包含查询所需所有列");
        
        private final String name;
        private final String description;
        
        IndexType(String name, String description) {
            this.name = name;
            this.description = description;
        }
    }
    
    /**
     * 复合索引设计示例
     */
    public static void demonstrateCompositeIndex() {
        String example = """
            -- 业务场景:用户订单查询
            -- 常见查询模式:
            -- 1. WHERE user_id = ? AND status = ?
            -- 2. WHERE user_id = ? AND status = ? ORDER BY created_at DESC
            -- 3. WHERE user_id = ? ORDER BY created_at DESC
            
            -- 最优复合索引设计
            CREATE INDEX idx_orders_user_status_time 
            ON orders(user_id, status, created_at DESC);
            
            -- 索引列顺序说明:
            -- 1. user_id:等值查询,选择性高,放第一位
            -- 2. status:等值查询,选择性中等,放第二位  
            -- 3. created_at:范围查询和排序,放最后
            
            -- 该索引可以支持的查询:
            -- ✅ WHERE user_id = ?
            -- ✅ WHERE user_id = ? AND status = ?
            -- ✅ WHERE user_id = ? AND status = ? ORDER BY created_at
            -- ✅ WHERE user_id = ? ORDER BY created_at
            -- ❌ WHERE status = ? (不符合最左前缀)
            """;
        System.out.println(example);
    }
    
    /**
     * 覆盖索引设计
     */
    public static void demonstrateCoveringIndex() {
        String example = """
            -- 业务场景:用户列表查询
            SELECT id, name, email, status 
            FROM users 
            WHERE status = 'ACTIVE' 
            ORDER BY created_at DES

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

Java面试圣经 文章被收录于专栏

Java面试圣经,带你练透java圣经

全部评论
欢迎讨论
点赞 回复 分享
发布于 2025-09-06 08:29 江西

相关推荐

评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务