SQL性能优化与索引策略实战

从原理到实战,掌握数据库性能优化的核心技能


一、优化核心原理

SQL执行过程 语法解析 查询优化器 执行计划生成 存储引擎执行 结果返回 优化核心目标 减少IO操作 降低CPU消耗 减少内存使用 减少数据扫描量 避免复杂计算 合理使用缓存

1.1 SQL 执行流程与瓶颈

sql 复制代码
-- 瓶颈检测示例
SELECT 
    '全表扫描' as 问题类型,
    COUNT(*) as 影响行数,
    table_name as 表名
FROM information_schema.tables 
WHERE TABLE_ROWS > 1000000;

1.2 优化器工作原理

  • 基于成本的优化(CBO):计算不同执行计划的代价
  • 统计信息:表大小、索引选择性、数据分布
  • 连接算法选择:Nested Loop、Hash Join、Sort Merge Join

二、索引策略全解

高基数 全文搜索 空间数据 Key-Value WHERE条件 排序需求 覆盖查询 索引类型选择 数据特征分析 B-Tree索引 全文索引 空间索引 哈希索引 复合索引设计 最左前缀匹配 ORDER BY字段 包含SELECT字段 索引优化策略 避免过多索引 定期重建索引 监控索引使用

2.1 索引类型对比表

索引类型 适用场景 优点 缺点 MySQL 示例
B-Tree 范围查询、排序 支持范围查询、排序 更新成本高 CREATE INDEX idx_name ON users(name)
哈希索引 等值查询 O(1) 查询速度 不支持范围查询 CREATE INDEX idx_hash USING HASH
全文索引 文本搜索 支持自然语言搜索 仅限文本字段 FULLTEXT(content)
空间索引 GIS 数据 高效空间查询 特定数据类型 SPATIAL INDEX(geom)
复合索引 多条件查询 覆盖多个查询 顺序敏感 INDEX(dept, status, date)

2.2 索引设计决策树

sql 复制代码
-- 索引设计自动化建议脚本
SELECT 
    t.TABLE_NAME,
    c.COLUMN_NAME,
    c.DATA_TYPE,
    COUNT(DISTINCT c.COLUMN_NAME) as distinct_count,
    t.TABLE_ROWS,
    ROUND(COUNT(DISTINCT c.COLUMN_NAME) * 100.0 / t.TABLE_ROWS, 2) as selectivity
FROM information_schema.COLUMNS c
JOIN information_schema.TABLES t ON c.TABLE_NAME = t.TABLE_NAME
WHERE t.TABLE_SCHEMA = 'your_database'
    AND t.TABLE_ROWS > 10000
    AND c.COLUMN_NAME IN (
        -- 分析常用查询条件
        SELECT COLUMN_NAME 
        FROM information_schema.STATISTICS 
        WHERE INDEX_NAME = 'PRIMARY'
    )
GROUP BY t.TABLE_NAME, c.COLUMN_NAME
HAVING selectivity > 10  -- 选择性大于10%考虑建索引
ORDER BY t.TABLE_ROWS DESC;

2.3 索引维护策略

sql 复制代码
-- 1. 索引使用率监控
SELECT 
    object_name,
    index_name,
    range_scans,
    singleton_lookups,
    (range_scans + singleton_lookups) as total_usage
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID('your_db');

-- 2. 索引碎片整理计划
SELECT 
    name as index_name,
    avg_fragmentation_in_percent,
    CASE 
        WHEN avg_fragmentation_in_percent > 30 THEN 'REBUILD'
        WHEN avg_fragmentation_in_percent > 10 THEN 'REORGANIZE'
        ELSE 'OK'
    END as action_required
FROM sys.dm_db_index_physical_stats(
    DB_ID('your_db'), 
    NULL, NULL, NULL, 'LIMITED'
) AS a
JOIN sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id
WHERE avg_fragmentation_in_percent > 5;

三、查询优化实战

满意 不满意 发现慢查询 分析执行计划 全表扫描 索引失效 连接低效 添加合适索引 重写查询条件 优化连接顺序 验证优化效果 记录优化方案 考虑其他策略 调整数据结构 使用物化视图 分区表策略

3.1 案例:电商订单查询优化

原始业务场景
sql 复制代码
-- 业务需求:查询某用户最近3个月的订单详情,包含商品信息
SELECT 
    o.*,
    oi.product_name,
    oi.quantity,
    oi.price,
    u.username,
    u.email
FROM orders o
JOIN order_items oi ON o.order_id = oi.order_id
JOIN users u ON o.user_id = u.user_id
WHERE o.user_id = 12345
    AND o.order_date >= DATE_SUB(NOW(), INTERVAL 3 MONTH)
    AND o.status IN ('paid', 'shipped')
ORDER BY o.order_date DESC
LIMIT 50;
性能问题诊断
sql 复制代码
-- EXPLAIN 输出分析
EXPLAIN FORMAT=JSON 
SELECT ... -- 上述查询

-- 输出结果分析表
步骤 type key rows Extra 问题分析
驱动表 ref idx_user 500 Using where 正常
orders 表 ALL NULL 1000000 Using where; Using filesort 全表扫描 + 文件排序
order_items ref idx_order 3 NULL 正常
users eq_ref PRIMARY 1 NULL 正常

诊断结果

  1. 订单表缺少 (user_id, order_date, status) 复合索引
  2. 排序导致临时文件
  3. 查询列过多导致回表操作频繁
优化方案实施
sql 复制代码
-- 方案1:创建优化索引
CREATE INDEX idx_user_order_composite ON orders(user_id, order_date DESC, status)
INCLUDE (total_amount, shipping_address);  -- SQL Server/PostgreSQL

-- MySQL 8.0+ 可以使用降序索引
CREATE INDEX idx_user_order_desc ON orders(user_id, order_date DESC, status);

-- 方案2:使用覆盖索引优化
CREATE INDEX idx_covering_optimized ON orders(
    user_id, 
    order_date DESC, 
    status, 
    total_amount, 
    shipping_address
);

-- 方案3:分页优化(处理深度分页)
SELECT /*+ INDEX(o idx_user_order_desc) */
    o.order_id,
    o.order_date,
    o.total_amount,
    -- 其他必要字段
FROM orders o
WHERE o.user_id = 12345
    AND o.order_date >= '2024-01-01'
    AND o.status IN ('paid', 'shipped')
    AND o.order_date < ?last_seen_date  -- 游标分页
ORDER BY o.order_date DESC
LIMIT 50;
性能对比数据
优化阶段 执行时间 扫描行数 临时表 文件排序 性能提升
优化前 2.3秒 1,050,000 -
加索引后 0.15秒 850 15倍
覆盖索引 0.08秒 50 28倍
分页优化 0.03秒 50 76倍

3.2 高级 JOIN 优化技巧

sql 复制代码
-- 案例:多表关联优化
-- 原始查询
SELECT 
    p.product_id,
    p.product_name,
    c.category_name,
    s.supplier_name,
    SUM(oi.quantity) as total_sold,
    AVG(oi.price) as avg_price
FROM products p
LEFT JOIN categories c ON p.category_id = c.category_id
LEFT JOIN suppliers s ON p.supplier_id = s.supplier_id
LEFT JOIN order_items oi ON p.product_id = oi.product_id
LEFT JOIN orders o ON oi.order_id = o.order_id
WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY p.product_id, p.product_name, c.category_name, s.supplier_name
HAVING total_sold > 100;

-- 优化方案:使用派生表减少 JOIN 次数
WITH product_sales AS (
    SELECT 
        oi.product_id,
        SUM(oi.quantity) as total_sold,
        AVG(oi.price) as avg_price
    FROM order_items oi
    JOIN orders o ON oi.order_id = o.order_id
    WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31'
    GROUP BY oi.product_id
    HAVING SUM(oi.quantity) > 100
)
SELECT 
    p.product_id,
    p.product_name,
    c.category_name,
    s.supplier_name,
    ps.total_sold,
    ps.avg_price
FROM products p
JOIN product_sales ps ON p.product_id = ps.product_id
LEFT JOIN categories c ON p.category_id = c.category_id
LEFT JOIN suppliers s ON p.supplier_id = s.supplier_id;

四、EXPLAIN 深度解析

system/const eq_ref/ref range index ALL EXPLAIN 分析 type字段分析 key字段分析 rows字段分析 Extra字段分析 访问类型判断 最优 良好 中等 需优化 紧急优化 Using index Using temporary Using filesort 覆盖索引, 性能好 创建临时表, 需优化 额外排序, 需优化 优化建议生成 添加索引 重写查询 调整JOIN顺序

4.1 EXPLAIN 全字段解读表

字段 含义 理想值 优化建议
id 查询序列号 数字越小优先级越高 检查子查询是否可以改写
select_type 查询类型 SIMPLE, PRIMARY 避免 DEPENDENT SUBQUERY
table 访问的表 - 查看分区信息
partitions 匹配的分区 NULL(未分区) 考虑分区优化
type 访问类型 system > const > eq_ref > ref > range 避免 index, ALL
possible_keys 可能使用的索引 包含实际使用的索引 检查索引选择
key 实际使用的索引 非 NULL NULL 表示未用索引
key_len 索引使用的字节数 尽可能小 检查索引是否完全使用
ref 列与索引的比较 const, 列名 检查连接条件
rows 预估扫描行数 尽可能少 大于10000需优化
filtered 条件过滤百分比 接近100% 低值表示索引效率低
Extra 额外信息 Using index 避免 Using temporary, filesort

4.2 实战:解读复杂查询的 EXPLAIN

sql 复制代码
-- 复杂查询示例
EXPLAIN FORMAT=JSON
SELECT 
    d.dept_name,
    COUNT(e.emp_id) as emp_count,
    AVG(e.salary) as avg_salary,
    MAX(e.hire_date) as latest_hire
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
WHERE e.status = 'active'
    AND e.salary > 5000
    AND d.location = 'Beijing'
GROUP BY d.dept_id
HAVING emp_count > 5
ORDER BY avg_salary DESC;

-- EXPLAIN 输出解析(简化版)
{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "1256.72"  -- 总成本
    },
    "ordering_operation": {
      "using_filesort": true,  -- 存在文件排序!
      "grouping_operation": {
        "using_temporary_table": true,  -- 存在临时表!
        "nested_loop": [
          {
            "table": {
              "table_name": "d",
              "access_type": "ref",  -- 索引访问
              "key": "idx_location",
              "rows": 3,
              "filtered": 100
            }
          },
          {
            "table": {
              "table_name": "e",
              "access_type": "ref",  -- 索引访问
              "key": "idx_dept_status",
              "rows": 245,
              "filtered": 33.33  -- 过滤比例低!
            }
          }
        ]
      }
    }
  }
}

优化建议

  1. 添加复合索引:(dept_id, status, salary)
  2. 考虑使用覆盖索引包含 hire_date
  3. 调整查询顺序,先过滤再连接

五、高级优化技巧

5.1 分区表策略

> 10GB < 10GB 时间范围查询 地域查询 类别查询 数据分区决策 数据量大小 建议分区 索引优化即可 访问模式分析 按时间分区 按地域分区 按类别分区 分区类型选择 范围分区 Range 列表分区 List 哈希分区 Hash 键分区 Key 分区维护 定期清理旧分区 分区统计信息更新 分区平衡调整

sql 复制代码
-- 分区表示例:按时间分区
CREATE TABLE orders_partitioned (
    order_id BIGINT AUTO_INCREMENT,
    user_id INT NOT NULL,
    order_date DATETIME NOT NULL,
    amount DECIMAL(10,2),
    status VARCHAR(20),
    PRIMARY KEY (order_id, order_date)  -- 分区键必须在主键中
)
PARTITION BY RANGE (YEAR(order_date)) (
    PARTITION p2020 VALUES LESS THAN (2021),
    PARTITION p2021 VALUES LESS THAN (2022),
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024),
    PARTITION p2024 VALUES LESS THAN (2025),
    PARTITION p_future VALUES LESS THAN MAXVALUE
);

-- 查询分区信息
SELECT 
    PARTITION_NAME,
    TABLE_ROWS,
    AVG_ROW_LENGTH,
    DATA_LENGTH
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'orders_partitioned';

-- 分区维护操作
-- 添加新分区
ALTER TABLE orders_partitioned REORGANIZE PARTITION p_future INTO (
    PARTITION p2025 VALUES LESS THAN (2026),
    PARTITION p_future VALUES LESS THAN MAXVALUE
);

-- 删除旧分区
ALTER TABLE orders_partitioned DROP PARTITION p2020;

5.2 物化视图优化

sql 复制代码
-- 创建物化视图(MySQL 8.0+ 通过表实现)
CREATE TABLE sales_summary_mv (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100),
    category_id INT,
    total_sold DECIMAL(12,2),
    avg_price DECIMAL(10,2),
    sale_count INT,
    last_updated TIMESTAMP,
    INDEX idx_category (category_id)
) ENGINE=InnoDB;

-- 刷新物化视图的存储过程
DELIMITER //
CREATE PROCEDURE refresh_sales_summary()
BEGIN
    -- 使用事务保证数据一致性
    START TRANSACTION;
    
    TRUNCATE TABLE sales_summary_mv;
    
    INSERT INTO sales_summary_mv
    SELECT 
        p.product_id,
        p.product_name,
        p.category_id,
        SUM(oi.quantity * oi.price) as total_sold,
        AVG(oi.price) as avg_price,
        COUNT(DISTINCT oi.order_id) as sale_count,
        NOW() as last_updated
    FROM products p
    JOIN order_items oi ON p.product_id = oi.product_id
    JOIN orders o ON oi.order_id = o.order_id
    WHERE o.order_date >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
    GROUP BY p.product_id;
    
    COMMIT;
END //
DELIMITER ;

-- 创建事件定期刷新
CREATE EVENT refresh_sales_summary_event
ON SCHEDULE EVERY 1 HOUR
DO CALL refresh_sales_summary();

六、性能监控体系

性能监控体系 实时监控 历史分析 预警系统 活跃会话监控 资源使用率 慢查询实时捕获 性能趋势分析 索引使用统计 查询模式分析 阈值设置 自动告警 优化建议生成 监控工具链 Prometheus + Grafana pt-query-digest Percona Monitoring 自研监控平台

6.1 全面监控 SQL

sql 复制代码
-- 1. 实时性能监控
SELECT 
    esh.EVENT_ID,
    esh.THREAD_ID,
    esh.EVENT_NAME,
    esh.TIMER_WAIT/1000000000 as wait_seconds,
    esh.SQL_TEXT,
    esh.CURRENT_SCHEMA,
    esh.ROWS_EXAMINED,
    esh.ROWS_SENT
FROM performance_schema.events_statements_history esh
WHERE esh.TIMER_WAIT > 1000000000  -- 超过1秒
ORDER BY esh.TIMER_WAIT DESC
LIMIT 10;

-- 2. 索引使用统计
SELECT 
    OBJECT_NAME as table_name,
    INDEX_NAME as index_name,
    COUNT_READ as read_count,
    COUNT_WRITE as write_cost,
    ROUND(COUNT_READ * 100.0 / NULLIF(COUNT_READ + COUNT_WRITE, 0), 2) as read_ratio
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = DATABASE()
ORDER BY COUNT_READ DESC;

-- 3. 表访问热力图
SELECT 
    table_name,
    rows_fetched,
    rows_inserted,
    rows_updated,
    rows_deleted,
    io_read_requests,
    io_write_requests,
    (rows_fetched + rows_inserted + rows_updated + rows_deleted) as total_operations
FROM sys.schema_table_statistics
WHERE table_schema = DATABASE()
ORDER BY total_operations DESC;

6.2 自动化优化建议系统

sql 复制代码
-- 自动生成优化建议
CREATE VIEW optimization_recommendations AS
SELECT 
    '索引优化' as category,
    CONCAT('为表 ', table_name, ' 的列 ', column_name, ' 创建索引') as recommendation,
    ROUND(selectivity * 100, 2) as benefit_score
FROM (
    SELECT 
        t.TABLE_NAME,
        c.COLUMN_NAME,
        COUNT(DISTINCT c.COLUMN_NAME) * 1.0 / MAX(t.TABLE_ROWS) as selectivity
    FROM information_schema.COLUMNS c
    JOIN information_schema.TABLES t ON c.TABLE_NAME = t.TABLE_NAME
    LEFT JOIN information_schema.STATISTICS s 
        ON c.TABLE_NAME = s.TABLE_NAME AND c.COLUMN_NAME = s.COLUMN_NAME
    WHERE t.TABLE_SCHEMA = DATABASE()
        AND t.TABLE_ROWS > 10000
        AND s.INDEX_NAME IS NULL  -- 没有索引
        AND c.COLUMN_NAME NOT LIKE '%id'  -- 排除ID字段
    GROUP BY t.TABLE_NAME, c.COLUMN_NAME
    HAVING selectivity > 0.1
) AS candidate_indexes

UNION ALL

SELECT 
    '查询优化' as category,
    CONCAT('优化查询: ', LEFT(digest_text, 100)) as recommendation,
    ROUND(avg_timer_wait / 1000000000, 2) as benefit_score
FROM performance_schema.events_statements_summary_by_digest
WHERE avg_timer_wait > 1000000000  -- 超过1秒
ORDER BY benefit_score DESC;

七、实战案例演练

7.1 案例:社交平台消息系统优化

业务场景:千万级用户的消息系统,需要支持:

  1. 按对话和时间查询消息
  2. 消息状态实时更新
  3. 未读消息数统计
  4. 消息搜索功能

原始设计问题

sql 复制代码
-- 原始表结构
CREATE TABLE messages (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    sender_id INT,
    receiver_id INT,
    conversation_id VARCHAR(100),  -- 冗余字段
    content TEXT,
    created_at DATETIME,
    is_read BOOLEAN DEFAULT FALSE,
    INDEX idx_sender (sender_id),
    INDEX idx_receiver (receiver_id),
    INDEX idx_created (created_at)
);

优化方案

sql 复制代码
-- 1. 分区表设计
CREATE TABLE messages_optimized (
    id BIGINT AUTO_INCREMENT,
    sender_id INT NOT NULL,
    receiver_id INT NOT NULL,
    conversation_id BIGINT NOT NULL,  -- 改为数值型
    content TEXT,
    created_at DATETIME NOT NULL,
    is_read BOOLEAN DEFAULT FALSE,
    -- 复合主键支持分区
    PRIMARY KEY (conversation_id, created_at, id),
    -- 覆盖索引设计
    INDEX idx_user_conversation (sender_id, receiver_id, created_at DESC),
    INDEX idx_conversation_unread (conversation_id, is_read, created_at DESC),
    -- 全文索引支持搜索
    FULLTEXT idx_content_search (content)
) ENGINE=InnoDB
PARTITION BY HASH(conversation_id % 100)  -- 按对话哈希分区
PARTITIONS 100;

-- 2. 物化视图优化未读计数
CREATE TABLE unread_count_mv (
    user_id INT PRIMARY KEY,
    conversation_id BIGINT,
    unread_count INT NOT NULL DEFAULT 0,
    last_message_time DATETIME,
    INDEX idx_user_conversation (user_id, conversation_id)
);

-- 3. 消息查询优化示例
EXPLAIN ANALYZE  -- MySQL 8.0+ 提供实际执行时间
SELECT 
    m.*,
    u1.username as sender_name,
    u2.username as receiver_name
FROM messages_optimized m
FORCE INDEX (idx_conversation_unread)  -- 强制使用最优索引
JOIN users u1 ON m.sender_id = u1.user_id
JOIN users u2 ON m.receiver_id = u2.user_id
WHERE m.conversation_id = 123456
    AND m.created_at >= '2024-01-01'
ORDER BY m.created_at DESC
LIMIT 50;

性能对比结果

指标 优化前 优化后 提升倍数
查询响应时间 1.8秒 0.05秒 36倍
写入吞吐量 1200 TPS 4500 TPS 3.75倍
磁盘空间 1.2TB 0.9TB 减少25%
内存使用 16GB 8GB 减少50%

八、优化决策流程

索引问题 查询问题 结构问题 配置问题 单列查询 复合条件 覆盖查询 复杂JOIN 大量数据 频繁聚合 数据量大 访问模式固定 实时性要求高 是 否 发现性能问题 收集诊断信息 分析EXPLAIN执行计划 识别瓶颈类型 索引优化方案 查询重写方案 结构调整方案 参数调优方案 索引选择 单列索引 复合索引 覆盖索引 查询模式 简化JOIN/子查询 分批处理 物化视图 数据特征 分区表 预聚合表 读写分离 实施优化方案 AB测试验证 性能达标? 上线并监控 调整方案 建立基线指标 定期复审 持续优化循环

8.1 优化检查清单

markdown 复制代码
# SQL 优化检查清单 ✅

## 索引优化
- [ ] 为 WHERE 条件列建立索引
- [ ] 为 JOIN 条件列建立索引
- [ ] 为 ORDER BY/GROUP BY 列建立索引
- [ ] 使用复合索引遵循最左前缀原则
- [ ] 考虑覆盖索引减少回表
- [ ] 索引字段选择性 > 10%
- [ ] 定期检查索引使用率
- [ ] 删除冗余和未使用的索引

## 查询优化
- [ ] 避免 SELECT *,指定需要的列
- [ ] 使用 EXISTS 代替 IN 对于子查询
- [ ] 使用 UNION ALL 代替 UNION(如果不需要去重)
- [ ] 避免在 WHERE 子句中使用函数
- [ ] 使用批处理操作减少交互次数
- [ ] 合理使用 LIMIT 限制结果集
- [ ] 避免深度分页,使用游标分页
- [ ] 拆分复杂查询为多个简单查询

## 结构优化
- [ ] 选择合适的数据类型(尽量小)
- [ ] 使用 NOT NULL 约束
- [ ] 规范化与反规范化平衡
- [ ] 考虑分区表(数据量 > 10GB)
- [ ] 使用物化视图预计算
- [ ] 读写分离架构
- [ ] 冷热数据分离

## 配置优化
- [ ] 合理设置缓冲池大小
- [ ] 调整连接池配置
- [ ] 配置查询缓存(适合场景)
- [ ] 优化日志配置
- [ ] 定期更新统计信息

8.2 性能优化跟踪表

sql 复制代码
-- 创建优化跟踪表
CREATE TABLE sql_optimization_log (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    original_sql TEXT NOT NULL,
    optimized_sql TEXT NOT NULL,
    optimization_type ENUM('INDEX', 'QUERY', 'STRUCTURE', 'CONFIG'),
    performance_before JSON,  -- 优化前性能指标
    performance_after JSON,   -- 优化后性能指标
    improvement_ratio DECIMAL(5,2),  -- 提升比例
    execution_plan_before TEXT,
    execution_plan_after TEXT,
    optimized_by VARCHAR(100),
    optimized_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    notes TEXT,
    INDEX idx_optimization_date (optimized_at),
    INDEX idx_improvement_ratio (improvement_ratio DESC)
);

-- 记录优化案例
INSERT INTO sql_optimization_log (
    original_sql,
    optimized_sql,
    optimization_type,
    performance_before,
    performance_after,
    improvement_ratio,
    execution_plan_before,
    execution_plan_after
) VALUES (
    'SELECT * FROM orders WHERE DATE(order_date) = "2024-01-15"',
    'SELECT order_id, customer_id FROM orders WHERE order_date >= "2024-01-15" AND order_date < "2024-01-16"',
    'QUERY',
    '{"execution_time": "2.3s", "rows_examined": 1000000, "filesort": true}',
    '{"execution_time": "0.15s", "rows_examined": 1500, "filesort": false}',
    15.33,  -- 15倍提升
    'type: ALL, key: NULL, rows: 1000000',
    'type: range, key: idx_order_date, rows: 1500'
);

📈 总结与最佳实践

优化层次理论

SQL优化金字塔 最有效
索引优化 查询重写 结构调整 配置调优 最少效果
硬件升级 减少数据扫描 优化执行路径 改变数据组织 调整数据库参数 ROI原则 20%的优化带来80%的效果 优先优化最频繁的查询 关注业务关键路径

优化优先级矩阵

优化类型 实施难度 效果程度 推荐优先级 适用场景
索引优化 ★★★★★ 所有查询性能问题
查询重写 ★★★★☆ 复杂查询、子查询
覆盖索引 中高 ★★★★☆ 频繁查询的宽表
分区表 ★★★☆☆ 数据量 > 10GB,有明显分区键
物化视图 ★★★☆☆ 频繁聚合查询
配置调优 ★★☆☆☆ 系统级性能问题
架构调整 极高 ★☆☆☆☆ 千万级以上数据量
相关推荐
郝学胜-神的一滴2 小时前
Linux C++ 守护进程开发指南
linux·运维·服务器·开发语言·c++·程序人生·性能优化
张人玉2 小时前
c# Data相关类
数据库·oracle
云和数据.ChenGuang2 小时前
OpenEuler 系统中安装 MySQL
运维·数据库·mysql·adb·运维工程师·运维技术
wniuniu_2 小时前
ceph中的rbd的稀疏写入
java·服务器·数据库
科技块儿2 小时前
如何使用IP数据云数据库接入流量监控?
数据库·网络协议·tcp/ip
叮咚侠2 小时前
Ubuntu 24.04.3 LTS如何扩容逻辑卷
linux·数据库·ubuntu
张人玉2 小时前
c#DataTable类
数据库·c#
风月歌2 小时前
基于微信小程序的学习资料销售平台源代码(源码+文档+数据库)
java·数据库·mysql·微信小程序·小程序·毕业设计·源码
gjc5922 小时前
【一次线上 MySQL 死锁问题的完整复盘与解析】
数据库·mysql·死锁