当前位置: 首页 > ops >正文

【MySQL】MySQL聚集索引与非聚集索引深度解析

目录

  1. 索引基础概念
  2. 聚集索引详解
  3. 非聚集索引详解
  4. 核心区别对比
  5. 性能影响分析
  6. 实际应用场景
  7. 最佳实践建议

索引基础概念

什么是索引

索引是数据库管理系统中一种重要的数据结构,它为表中的数据创建有序的访问路径,类似于书籍的目录。通过索引,数据库可以快速定位到所需的数据行,避免全表扫描,从而大幅提升查询性能。

索引的存储结构

MySQL中的索引主要基于B+树数据结构实现:

  • B+树特点:多路平衡查找树,所有叶子节点在同一层
  • 查询效率:时间复杂度为O(log n)
  • 范围查询:叶子节点通过指针连接,便于范围扫描
-- 查看表的索引信息
SHOW INDEX FROM table_name;-- 查看索引使用情况
EXPLAIN SELECT * FROM users WHERE id = 1;

聚集索引详解

定义与特点

聚集索引(Clustered Index)是一种特殊的索引类型,其特点是索引顺序与表中数据的物理存储顺序完全一致

核心特征

1. 物理存储顺序
聚集索引B+树结构:[Root Node]/          \[Internal]   [Internal]/    |    \   /    |    \
[Leaf] [Leaf] [Leaf] [Leaf] [Leaf]|      |      |      |      |
实际数据 实际数据 实际数据 实际数据 实际数据
2. 唯一性
  • 每个表最多只能有一个聚集索引
  • 聚集索引的叶子节点直接存储完整的数据行
3. InnoDB中的聚集索引

在InnoDB存储引擎中:

-- 主键自动成为聚集索引
CREATE TABLE users (id INT PRIMARY KEY,        -- 聚集索引name VARCHAR(50),email VARCHAR(100),created_at TIMESTAMP
);-- 如果没有主键,InnoDB会选择第一个唯一非空索引
CREATE TABLE products (sku VARCHAR(20) UNIQUE NOT NULL,  -- 成为聚集索引name VARCHAR(100),price DECIMAL(10,2)
);-- 如果没有合适的索引,InnoDB会创建隐藏的6字节ROWID
CREATE TABLE logs (message TEXT,level VARCHAR(10)-- InnoDB内部创建隐藏的ROWID作为聚集索引
);

聚集索引的工作原理

数据查询过程
-- 基于聚集索引的查询
SELECT * FROM users WHERE id = 100;

查询步骤:

  1. 从B+树根节点开始
  2. 根据id=100逐层向下查找
  3. 直接在叶子节点获取完整数据行
  4. 只需一次磁盘I/O操作
范围查询优势
-- 范围查询效率高
SELECT * FROM users WHERE id BETWEEN 100 AND 200;

由于数据物理有序,范围查询只需顺序扫描相邻的叶子节点。

聚集索引的优缺点

✅ 优点
  1. 查询速度快:直接获取数据,无需额外查找
  2. 范围查询高效:物理顺序与逻辑顺序一致
  3. 减少磁盘I/O:数据和索引存储在一起
❌ 缺点
  1. 插入性能影响:可能导致页分裂
  2. 更新主键代价高:需要重新组织数据
  3. 唯一性限制:每表只能有一个

非聚集索引详解

定义与特点

非聚集索引(Non-Clustered Index)是独立于数据存储的索引结构,索引顺序与数据物理存储顺序无关

核心特征

1. 逻辑结构分离
非聚集索引B+树结构:[Root Node]/          \[Internal]   [Internal]/    |    \   /    |    \
[Leaf] [Leaf] [Leaf] [Leaf] [Leaf]|      |      |      |      |
指向数据 指向数据 指向数据 指向数据 指向数据↓      ↓      ↓      ↓      ↓
[数据页] [数据页] [数据页] [数据页] [数据页]
2. 多样性
  • 一个表可以有多个非聚集索引
  • 叶子节点存储索引键值和指向数据的指针
3. 在InnoDB中的实现
-- 创建非聚集索引
CREATE TABLE users (id INT PRIMARY KEY,           -- 聚集索引name VARCHAR(50),email VARCHAR(100) UNIQUE,    -- 非聚集索引age INT,city VARCHAR(50),created_at TIMESTAMP,INDEX idx_name (name),        -- 非聚集索引INDEX idx_age_city (age, city), -- 复合非聚集索引INDEX idx_created (created_at)  -- 非聚集索引
);

非聚集索引的工作原理

InnoDB中的二次查找

在InnoDB中,非聚集索引的叶子节点存储的是主键值,需要进行"回表"操作:

-- 基于非聚集索引的查询
SELECT * FROM users WHERE name = 'John';

查询步骤:

  1. 在name索引的B+树中查找’John’
  2. 获取对应的主键值(如id=100)
  3. 使用主键值在聚集索引中查找
  4. 获取完整的数据行
  5. 需要两次磁盘I/O操作
覆盖索引优化
-- 创建覆盖索引,避免回表
CREATE INDEX idx_name_email ON users(name, email);-- 这个查询可以直接从索引获取所需数据
SELECT name, email FROM users WHERE name = 'John';

非聚集索引的优缺点

✅ 优点
  1. 数量不限:可创建多个索引满足不同查询需求
  2. 插入友好:不影响数据的物理存储顺序
  3. 灵活性高:可针对不同列组合创建索引
❌ 缺点
  1. 查询性能:需要回表操作,增加I/O开销
  2. 存储开销:额外的存储空间
  3. 维护成本:DML操作需要同时维护多个索引

核心区别对比

1. 存储方式对比

特性聚集索引非聚集索引
数据存储叶子节点直接存储数据行叶子节点存储指针或主键值
物理顺序与索引顺序一致与索引顺序无关
数据查找直接获取需要额外查找(回表)

2. 性能对比

-- 性能测试示例
CREATE TABLE performance_test (id INT PRIMARY KEY,                    -- 聚集索引name VARCHAR(50),email VARCHAR(100),score INT,INDEX idx_name (name),                 -- 非聚集索引INDEX idx_score (score)                -- 非聚集索引
);-- 插入测试数据
INSERT INTO performance_test (id, name, email, score) 
VALUES (1, 'Alice', 'alice@email.com', 95);-- 聚集索引查询(速度快)
SELECT * FROM performance_test WHERE id = 1;
-- 执行计划:type=const, rows=1-- 非聚集索引查询(需要回表)
SELECT * FROM performance_test WHERE name = 'Alice';
-- 执行计划:type=ref, extra=null(表示回表)-- 覆盖索引查询(速度快,无需回表)
SELECT name FROM performance_test WHERE name = 'Alice';
-- 执行计划:type=ref, extra=Using index

3. 数量限制对比

-- 聚集索引:每表最多1个
ALTER TABLE users ADD PRIMARY KEY (id);  -- 只能有一个主键-- 非聚集索引:可以有多个
CREATE INDEX idx_1 ON users(name);
CREATE INDEX idx_2 ON users(email);
CREATE INDEX idx_3 ON users(age, city);
CREATE INDEX idx_4 ON users(created_at);
-- ... 可以继续创建更多

4. 维护成本对比

插入操作影响
-- 聚集索引的插入可能导致页分裂
INSERT INTO users (id, name) VALUES (150, 'Bob');  -- 如果150插入到已满的页中-- 非聚集索引的插入相对简单
-- 只需在索引树中插入新的索引项
更新操作影响
-- 更新聚集索引键值(代价高)
UPDATE users SET id = 999 WHERE id = 1;  -- 可能需要移动整行数据-- 更新非聚集索引键值(代价相对较低)
UPDATE users SET name = 'NewName' WHERE id = 1;  -- 只需更新索引项

性能影响分析

1. 查询性能

单行查询
-- 聚集索引查询(最优)
SELECT * FROM users WHERE id = 1;
-- I/O次数:1次,直接命中-- 非聚集索引查询
SELECT * FROM users WHERE email = 'test@email.com';
-- I/O次数:2次,索引查找 + 回表-- 覆盖索引查询(优化)
SELECT id, email FROM users WHERE email = 'test@email.com';
-- I/O次数:1次,无需回表
范围查询
-- 聚集索引范围查询(高效)
SELECT * FROM users WHERE id BETWEEN 100 AND 200;
-- 连续的磁盘读取,效率高-- 非聚集索引范围查询
SELECT * FROM users WHERE age BETWEEN 25 AND 35;
-- 可能需要多次随机I/O,效率较低

2. 插入性能

顺序插入 vs 随机插入
-- 聚集索引顺序插入(高效)
INSERT INTO users (id, name) VALUES (1001, 'User1'),(1002, 'User2'),(1003, 'User3');-- 聚集索引随机插入(可能导致页分裂)
INSERT INTO users (id, name) VALUES (505, 'User505'),  -- 插入到中间位置(203, 'User203'),(799, 'User799');
页分裂现象
-- 监控页分裂
SHOW GLOBAL STATUS LIKE 'innodb_page_splits';-- 优化:使用AUTO_INCREMENT避免随机插入
CREATE TABLE optimized_users (id INT AUTO_INCREMENT PRIMARY KEY,  -- 顺序增长name VARCHAR(50),email VARCHAR(100)
);

3. 存储空间

-- 查看表和索引的存储空间
SELECT table_name,ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Total Size (MB)',ROUND((data_length / 1024 / 1024), 2) AS 'Data Size (MB)',ROUND((index_length / 1024 / 1024), 2) AS 'Index Size (MB)'
FROM information_schema.tables
WHERE table_schema = 'your_database'
AND table_name = 'your_table';

实际应用场景

1. 电商平台场景

用户系统
-- 用户表设计(千万级用户)
CREATE TABLE users (user_id BIGINT AUTO_INCREMENT PRIMARY KEY,    -- 聚集索引,用于主键查询mobile VARCHAR(20) UNIQUE,                    -- 非聚集索引,手机号登录email VARCHAR(100) UNIQUE,                    -- 非聚集索引,邮箱登录username VARCHAR(50),                         password_hash VARCHAR(255),status TINYINT DEFAULT 1,                     -- 1:正常 0:禁用register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,last_login_time TIMESTAMP,-- 业务查询索引INDEX idx_mobile (mobile),                    -- 手机号登录:SELECT * FROM users WHERE mobile = '13812345678'INDEX idx_email (email),                      -- 邮箱登录:SELECT * FROM users WHERE email = 'user@example.com'  INDEX idx_status_register (status, register_time), -- 用户统计:按状态和注册时间INDEX idx_last_login (last_login_time)        -- 活跃用户分析
);-- 实际生产查询场景
-- 1. 用户登录(每日千万次)
SELECT user_id, username, status FROM users WHERE mobile = '13812345678' AND password_hash = 'xxx';-- 2. 用户详情页(高频查询)
SELECT * FROM users WHERE user_id = 123456;  -- 聚集索引,最快-- 3. 运营分析查询
SELECT COUNT(*) FROM users WHERE status = 1 AND register_time >= '2024-01-01';  -- 使用复合索引-- 4. 找回密码功能
SELECT user_id, username FROM users WHERE email = 'user@example.com';
订单系统
-- 订单表(亿级订单量)
CREATE TABLE orders (order_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引order_no VARCHAR(32) UNIQUE,                  -- 业务订单号,给用户看的user_id BIGINT,                               -- 买家IDseller_id BIGINT,                             -- 卖家ID  total_amount DECIMAL(15,2),                   -- 订单总金额order_status TINYINT,                         -- 订单状态:1待付款 2已付款 3已发货 4已完成 5已取消payment_status TINYINT,                       -- 支付状态created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 核心业务索引INDEX idx_order_no (order_no),               -- 订单号查询:用户查看订单详情INDEX idx_user_status_time (user_id, order_status, created_at), -- 用户订单列表INDEX idx_seller_status_time (seller_id, order_status, created_at), -- 商家订单管理INDEX idx_status_amount (order_status, total_amount), -- 财务对账INDEX idx_created_time (created_at),          -- 按时间范围统计订单INDEX idx_payment_status (payment_status, created_at) -- 支付相关查询
);-- 生产环境查询实例
-- 1. 用户查看自己的订单(用户APP中最频繁的查询)
SELECT order_id, order_no, total_amount, order_status, created_at 
FROM orders 
WHERE user_id = 123456 AND order_status IN (1,2,3,4) 
ORDER BY created_at DESC LIMIT 20;  -- 使用 idx_user_status_time-- 2. 订单详情查询(通过订单号)
SELECT * FROM orders WHERE order_no = 'ORD20241201123456';  -- 使用 idx_order_no-- 3. 商家订单管理
SELECT order_id, order_no, user_id, total_amount, order_status, created_at
FROM orders 
WHERE seller_id = 789 AND order_status = 2 
AND created_at >= '2024-12-01' 
ORDER BY created_at DESC;  -- 使用 idx_seller_status_time-- 4. 财务日报(每日定时任务)
SELECT DATE(created_at) as order_date,COUNT(*) as order_count,SUM(total_amount) as total_revenue
FROM orders 
WHERE order_status = 4  -- 已完成订单
AND created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY DATE(created_at);  -- 使用 idx_status_amount 和 idx_created_time
商品系统
-- 商品表(百万级商品)
CREATE TABLE products (product_id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 聚集索引sku VARCHAR(50) UNIQUE,                        -- 商品SKU,唯一标识spu_id BIGINT,                                 -- 标准产品单元IDcategory_id INT,                               -- 分类IDbrand_id INT,                                  -- 品牌IDtitle VARCHAR(500),                            -- 商品标题price DECIMAL(10,2),                          -- 价格stock_quantity INT,                           -- 库存数量sales_count INT DEFAULT 0,                    -- 销量status TINYINT DEFAULT 1,                     -- 1上架 0下架created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,-- 搜索和筛选索引INDEX idx_sku (sku),                          -- SKU查询INDEX idx_category_status_sales (category_id, status, sales_count), -- 分类页面排序INDEX idx_brand_status (brand_id, status),    -- 品牌筛选INDEX idx_price_status (price, status),       -- 价格筛选INDEX idx_status_created (status, created_at), -- 新品上架INDEX idx_sales_status (sales_count, status), -- 热销排序FULLTEXT idx_title_search (title)             -- 全文搜索
);-- 商品搜索页面(用户最常用功能)
-- 1. 分类浏览 + 销量排序
SELECT product_id, title, price, sales_count 
FROM products 
WHERE category_id = 123 AND status = 1 
ORDER BY sales_count DESC LIMIT 20;  -- 使用 idx_category_status_sales-- 2. 价格区间筛选
SELECT product_id, title, price 
FROM products 
WHERE price BETWEEN 100.00 AND 500.00 AND status = 1
ORDER BY sales_count DESC;  -- 使用 idx_price_status-- 3. 品牌筛选
SELECT product_id, title, price, sales_count
FROM products 
WHERE brand_id = 456 AND status = 1
ORDER BY created_at DESC;  -- 使用 idx_brand_status-- 4. 商品详情(通过SKU,仓库管理常用)
SELECT * FROM products WHERE sku = 'PHONE-IPHONE15-256GB-BLACK';

2. 金融支付系统

支付流水表
-- 支付流水(十亿级记录)
CREATE TABLE payment_records (record_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引,自增IDpayment_no VARCHAR(32) UNIQUE,                 -- 支付单号,业务主键order_no VARCHAR(32),                          -- 关联订单号user_id BIGINT,                                -- 用户IDmerchant_id BIGINT,                            -- 商户IDamount DECIMAL(15,2),                          -- 支付金额currency VARCHAR(3) DEFAULT 'CNY',             -- 货币类型payment_method TINYINT,                        -- 支付方式:1微信 2支付宝 3银联 4余额payment_status TINYINT,                        -- 支付状态:1待支付 2支付中 3支付成功 4支付失败 5已退款transaction_id VARCHAR(64),                    -- 第三方交易IDcreated_at TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3), -- 毫秒级时间戳completed_at TIMESTAMP(3),                     -- 支付完成时间-- 业务查询索引INDEX idx_payment_no (payment_no),            -- 支付单号查询INDEX idx_order_no (order_no),                -- 通过订单号查支付记录INDEX idx_user_status_time (user_id, payment_status, created_at), -- 用户支付历史INDEX idx_merchant_time (merchant_id, created_at), -- 商户流水查询INDEX idx_status_method_time (payment_status, payment_method, created_at), -- 支付分析INDEX idx_transaction_id (transaction_id),     -- 第三方交易ID查询INDEX idx_amount_time (amount, created_at),    -- 大额交易监控INDEX idx_completed_time (completed_at)        -- 按完成时间统计
);-- 生产环境关键查询
-- 1. 支付状态查询(用户支付后轮询)
SELECT payment_status, amount, completed_at 
FROM payment_records 
WHERE payment_no = 'PAY20241201123456';  -- 使用聚集索引或唯一索引-- 2. 用户支付历史(用户中心)
SELECT payment_no, order_no, amount, payment_method, payment_status, created_at
FROM payment_records 
WHERE user_id = 123456 AND payment_status = 3
ORDER BY created_at DESC LIMIT 50;  -- 使用 idx_user_status_time-- 3. 商户对账(每日定时)
SELECT DATE(completed_at) as pay_date,COUNT(*) as transaction_count,SUM(amount) as total_amount
FROM payment_records 
WHERE merchant_id = 789 
AND payment_status = 3
AND completed_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY DATE(completed_at);  -- 使用 idx_merchant_time-- 4. 风控监控(大额交易实时监控)
SELECT record_id, payment_no, user_id, amount, created_at
FROM payment_records 
WHERE amount >= 10000.00 
AND created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND payment_status IN (2, 3);  -- 使用 idx_amount_time
账户余额表
-- 用户账户表
CREATE TABLE user_accounts (account_id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 聚集索引user_id BIGINT UNIQUE,                         -- 用户ID,一对一关系balance DECIMAL(15,2) DEFAULT 0.00,            -- 账户余额frozen_amount DECIMAL(15,2) DEFAULT 0.00,      -- 冻结金额total_recharge DECIMAL(15,2) DEFAULT 0.00,     -- 累计充值total_withdraw DECIMAL(15,2) DEFAULT 0.00,     -- 累计提现version INT DEFAULT 0,                         -- 乐观锁版本号status TINYINT DEFAULT 1,                      -- 账户状态created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,INDEX idx_user_id (user_id),                   -- 通过用户ID查账户INDEX idx_balance (balance),                   -- 余额查询(风控)INDEX idx_status (status)                      -- 账户状态筛选
);-- 余额变动记录表(用于对账和审计)
CREATE TABLE balance_changes (change_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引user_id BIGINT,                                -- 用户IDaccount_id BIGINT,                             -- 账户IDchange_type TINYINT,                           -- 变动类型:1充值 2消费 3提现 4退款 5奖励amount DECIMAL(15,2),                          -- 变动金额(正负数)balance_before DECIMAL(15,2),                  -- 变动前余额balance_after DECIMAL(15,2),                   -- 变动后余额business_no VARCHAR(32),                       -- 业务单号description VARCHAR(200),                      -- 变动描述created_at TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3),INDEX idx_user_time (user_id, created_at),     -- 用户余额变动历史INDEX idx_account_time (account_id, created_at), -- 账户变动记录INDEX idx_business_no (business_no),           -- 业务单号查询INDEX idx_type_time (change_type, created_at), -- 按类型统计INDEX idx_amount_time (amount, created_at)     -- 大额变动监控
);

3. 社交媒体/内容系统

用户动态表
-- 用户动态/朋友圈(亿级数据)
CREATE TABLE user_posts (post_id BIGINT AUTO_INCREMENT PRIMARY KEY,     -- 聚集索引user_id BIGINT,                                -- 发布用户IDcontent TEXT,                                  -- 动态内容image_urls JSON,                               -- 图片URL数组post_type TINYINT DEFAULT 1,                   -- 动态类型:1普通 2转发 3视频visibility TINYINT DEFAULT 1,                  -- 可见性:1公开 2好友 3私密like_count INT DEFAULT 0,                      -- 点赞数comment_count INT DEFAULT 0,                   -- 评论数share_count INT DEFAULT 0,                     -- 分享数status TINYINT DEFAULT 1,                      -- 状态:1正常 0删除created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 核心查询索引INDEX idx_user_status_time (user_id, status, created_at), -- 个人主页时间线INDEX idx_visibility_time (visibility, created_at),        -- 公开动态流INDEX idx_like_count_time (like_count, created_at),       -- 热门内容排序INDEX idx_type_status_time (post_type, status, created_at), -- 按类型筛选FULLTEXT idx_content_search (content)                      -- 内容全文搜索
);-- 生产环境查询场景
-- 1. 个人主页时间线(用户查看自己或他人的动态)
SELECT post_id, content, image_urls, like_count, comment_count, created_at
FROM user_posts 
WHERE user_id = 123456 AND status = 1
ORDER BY created_at DESC LIMIT 20;  -- 使用 idx_user_status_time-- 2. 公共动态流(首页推荐)
SELECT post_id, user_id, content, like_count, comment_count, created_at
FROM user_posts 
WHERE visibility = 1 AND status = 1
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY like_count DESC, created_at DESC LIMIT 50;  -- 使用 idx_visibility_time-- 3. 热门内容排行
SELECT post_id, user_id, content, like_count, comment_count
FROM user_posts 
WHERE status = 1 AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY like_count DESC LIMIT 100;  -- 使用 idx_like_count_time
关注关系表
-- 用户关注关系(千万级关系)
CREATE TABLE user_follows (follow_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引follower_id BIGINT,                            -- 关注者IDfollowing_id BIGINT,                           -- 被关注者IDstatus TINYINT DEFAULT 1,                      -- 关注状态:1关注 0取消关注created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 关键业务索引UNIQUE KEY uk_follower_following (follower_id, following_id), -- 防重复关注INDEX idx_follower_status (follower_id, status),              -- 我关注的人INDEX idx_following_status (following_id, status),            -- 关注我的人INDEX idx_following_time (following_id, created_at)           -- 粉丝时间排序
);-- 关注相关查询
-- 1. 我关注的人列表
SELECT following_id FROM user_follows 
WHERE follower_id = 123456 AND status = 1;-- 2. 关注我的人列表(粉丝列表)
SELECT follower_id FROM user_follows 
WHERE following_id = 123456 AND status = 1 
ORDER BY created_at DESC;-- 3. 检查关注关系(判断是否已关注)
SELECT status FROM user_follows 
WHERE follower_id = 123456 AND following_id = 789012;

4. 日志监控系统

应用日志表
-- 应用日志(每日千万级别)
CREATE TABLE application_logs (log_id BIGINT AUTO_INCREMENT PRIMARY KEY,      -- 聚集索引,时间顺序自增trace_id VARCHAR(32),                          -- 链路追踪IDapp_name VARCHAR(50),                          -- 应用名称log_level TINYINT,                             -- 日志级别:1DEBUG 2INFO 3WARN 4ERROR 5FATALlogger_name VARCHAR(200),                      -- 日志器名称message TEXT,                                  -- 日志消息exception_stack TEXT,                          -- 异常堆栈(如果有)user_id BIGINT,                                -- 用户ID(业务日志)ip_address VARCHAR(45),                        -- IP地址user_agent VARCHAR(500),                       -- 用户代理created_at TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3), -- 毫秒级时间戳-- 查询和监控索引INDEX idx_trace_id (trace_id),                 -- 链路追踪查询INDEX idx_app_level_time (app_name, log_level, created_at), -- 应用错误监控INDEX idx_level_time (log_level, created_at),  -- 按级别查询日志INDEX idx_user_time (user_id, created_at),     -- 用户行为日志INDEX idx_ip_time (ip_address, created_at),    -- IP地址分析INDEX idx_created_time (created_at),           -- 时间范围查询FULLTEXT idx_message_search (message)          -- 日志内容搜索
);-- 生产环境日志查询
-- 1. 链路追踪(问题排查最常用)
SELECT log_id, app_name, log_level, logger_name, message, created_at
FROM application_logs 
WHERE trace_id = 'trace-123456789'
ORDER BY created_at ASC;  -- 使用 idx_trace_id-- 2. 错误日志监控(实时告警)
SELECT COUNT(*) as error_count
FROM application_logs 
WHERE log_level >= 4  -- ERROR及以上级别
AND created_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE);  -- 最近5分钟-- 3. 应用健康检查
SELECT app_name,log_level,COUNT(*) as log_count
FROM application_logs 
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY app_name, log_level
ORDER BY app_name, log_level;  -- 使用 idx_app_level_time-- 4. 用户行为分析
SELECT message, created_at
FROM application_logs 
WHERE user_id = 123456 
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY created_at DESC;  -- 使用 idx_user_time
系统性能监控表
-- 系统性能指标(高频写入)
CREATE TABLE system_metrics (metric_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引,按时间自增server_name VARCHAR(100),                      -- 服务器名称metric_type VARCHAR(50),                       -- 指标类型:cpu, memory, disk, networkmetric_name VARCHAR(100),                      -- 具体指标名:cpu_usage, memory_used等metric_value DECIMAL(15,4),                    -- 指标值unit VARCHAR(20),                              -- 单位:%, MB, KB/s等tags JSON,                                     -- 标签(主机、环境等)collected_at TIMESTAMP(3),                     -- 采集时间created_at TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3),-- 监控查询索引INDEX idx_server_type_time (server_name, metric_type, collected_at), -- 服务器指标查询INDEX idx_type_name_time (metric_type, metric_name, collected_at),   -- 指标类型查询INDEX idx_collected_time (collected_at),                             -- 时间范围查询INDEX idx_server_collected (server_name, collected_at)               -- 服务器时间序列
);-- 性能监控查询
-- 1. 服务器CPU使用率趋势(最常用的监控图表)
SELECT collected_at,metric_value as cpu_usage
FROM system_metrics 
WHERE server_name = 'web-server-01' 
AND metric_type = 'cpu' 
AND metric_name = 'cpu_usage'
AND collected_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY collected_at ASC;  -- 使用 idx_server_type_time-- 2. 内存使用率告警检查
SELECT server_name, metric_value, collected_at
FROM system_metrics 
WHERE metric_type = 'memory' 
AND metric_name = 'memory_usage_percent'
AND metric_value >= 90.0  -- 内存使用率超过90%
AND collected_at >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
ORDER BY metric_value DESC;  -- 使用 idx_type_name_time-- 3. 磁盘空间监控
SELECT server_name,MAX(metric_value) as max_disk_usage
FROM system_metrics 
WHERE metric_type = 'disk' 
AND metric_name = 'disk_usage_percent'
AND collected_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY server_name
HAVING max_disk_usage >= 85.0;  -- 磁盘使用率超过85%

5. 物联网 (IoT) 数据处理系统

IoT传感器数据表
-- IoT传感器数据(每秒千万级数据写入)
CREATE TABLE sensor_data (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,时间序列自增device_id VARCHAR(50),                         -- 设备IDsensor_type TINYINT,                           -- 传感器类型:1温度 2湿度 3压力 4光照sensor_value DECIMAL(10,4),                    -- 传感器数值location_id INT,                               -- 地理位置IDfactory_id INT,                                -- 工厂IDworkshop_id INT,                               -- 车间IDis_abnormal TINYINT DEFAULT 0,                 -- 是否异常:0正常 1异常collected_at TIMESTAMP(3),                     -- 采集时间(毫秒精度)created_at TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3),-- 核心查询索引INDEX idx_device_type_time (device_id, sensor_type, collected_at), -- 设备历史数据查询INDEX idx_location_time (location_id, collected_at),               -- 区域环境监控INDEX idx_factory_abnormal (factory_id, is_abnormal, collected_at), -- 工厂异常监控INDEX idx_type_value_time (sensor_type, sensor_value, collected_at), -- 阈值告警查询INDEX idx_workshop_time (workshop_id, collected_at)                 -- 车间生产监控
);-- 生产环境IoT查询场景
-- 1. 实时设备监控(监控大屏每5秒刷新)
SELECT device_id,sensor_type,AVG(sensor_value) as avg_value,MAX(sensor_value) as max_value,COUNT(CASE WHEN is_abnormal = 1 THEN 1 END) as abnormal_count
FROM sensor_data 
WHERE factory_id = 101 
AND collected_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
GROUP BY device_id, sensor_type;  -- 使用 idx_factory_abnormal-- 2. 温度异常告警(每分钟检查)
SELECT device_id, sensor_value, collected_at
FROM sensor_data 
WHERE sensor_type = 1  -- 温度传感器
AND sensor_value > 80.0  -- 超过80度
AND collected_at >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)
AND is_abnormal = 0;  -- 避免重复告警-- 3. 设备历史趋势分析(用户查看设备曲线图)
SELECT DATE_FORMAT(collected_at, '%H:%i') as time_point,AVG(sensor_value) as avg_temp
FROM sensor_data 
WHERE device_id = 'TEMP_SENSOR_001' 
AND sensor_type = 1
AND collected_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY DATE_FORMAT(collected_at, '%H:%i')
ORDER BY time_point;  -- 使用 idx_device_type_time

6. 物流配送系统

快递运单表
-- 快递运单表(日处理量千万级)
CREATE TABLE express_orders (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,时间序列tracking_number VARCHAR(30) UNIQUE,            -- 运单号,对外展示order_no VARCHAR(32),                          -- 关联业务订单号sender_phone VARCHAR(20),                      -- 寄件人手机号receiver_phone VARCHAR(20),                    -- 收件人手机号sender_address VARCHAR(500),                   -- 寄件地址receiver_address VARCHAR(500),                 -- 收件地址sender_city_code VARCHAR(10),                  -- 寄件城市编码receiver_city_code VARCHAR(10),                -- 收件城市编码package_weight DECIMAL(8,3),                   -- 包裹重量(kg)freight_amount DECIMAL(10,2),                  -- 运费express_type TINYINT,                          -- 快递类型:1标准 2加急 3当日达current_status TINYINT,                        -- 当前状态:1已揽收 2运输中 3派送中 4已签收 5异常current_location VARCHAR(200),                 -- 当前位置courier_id BIGINT,                             -- 当前负责快递员IDestimated_delivery TIMESTAMP,                  -- 预计送达时间actual_delivery TIMESTAMP,                     -- 实际送达时间created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 业务核心索引INDEX idx_tracking_number (tracking_number),   -- 运单号查询(用户最常用)INDEX idx_receiver_phone (receiver_phone),     -- 收件人手机号查询INDEX idx_sender_phone (sender_phone),         -- 寄件人手机号查询INDEX idx_courier_status (courier_id, current_status), -- 快递员工作台INDEX idx_status_city_time (current_status, receiver_city_code, created_at), -- 城市配送统计INDEX idx_type_estimated (express_type, estimated_delivery), -- 时效统计INDEX idx_receiver_city_status (receiver_city_code, current_status) -- 区域配送管理
);-- 生产环境物流查询场景
-- 1. 用户查询物流信息(最高频查询)
SELECT tracking_number,current_status,current_location,estimated_delivery,updated_at
FROM express_orders 
WHERE tracking_number = 'SF1234567890123';  -- 使用唯一索引-- 2. 收件人查询包裹(手机号查询)
SELECT tracking_number,sender_phone,current_status,estimated_delivery
FROM express_orders 
WHERE receiver_phone = '13812345678'
AND current_status IN (1, 2, 3)  -- 未签收的包裹
ORDER BY created_at DESC;  -- 使用 idx_receiver_phone-- 3. 快递员工作台(派送任务管理)
SELECT tracking_number,receiver_phone,receiver_address,package_weight,estimated_delivery
FROM express_orders 
WHERE courier_id = 1001 
AND current_status = 3  -- 派送中状态
AND receiver_city_code = 'BJ001'  -- 北京区域
ORDER BY estimated_delivery ASC;  -- 使用 idx_courier_status

7. 游戏行业数据系统

游戏玩家数据表
-- 游戏玩家数据表(千万级玩家)
CREATE TABLE game_players (player_id BIGINT AUTO_INCREMENT PRIMARY KEY,   -- 聚集索引,玩家唯一IDplayer_uuid VARCHAR(36) UNIQUE,                -- 玩家UUID,跨服标识username VARCHAR(50) UNIQUE,                   -- 玩家用户名email VARCHAR(100),                            -- 邮箱phone VARCHAR(20),                             -- 手机号server_id INT,                                 -- 所在服务器IDlevel INT DEFAULT 1,                           -- 玩家等级experience BIGINT DEFAULT 0,                   -- 经验值gold BIGINT DEFAULT 0,                         -- 游戏金币diamond INT DEFAULT 0,                         -- 钻石数量vip_level TINYINT DEFAULT 0,                   -- VIP等级guild_id BIGINT,                               -- 公会IDlast_login_time TIMESTAMP,                     -- 最后登录时间total_playtime INT DEFAULT 0,                  -- 总游戏时长(分钟)player_status TINYINT DEFAULT 1,               -- 玩家状态:1正常 2封号 3注销register_ip VARCHAR(45),                       -- 注册IPregister_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 游戏业务索引INDEX idx_username (username),                 -- 用户名登录INDEX idx_server_level (server_id, level),     -- 服务器排行榜INDEX idx_guild_level (guild_id, level),       -- 公会成员排行INDEX idx_vip_level (vip_level, level),        -- VIP玩家分析INDEX idx_login_time (last_login_time),        -- 活跃玩家分析INDEX idx_status_register (player_status, register_time), -- 玩家注册分析INDEX idx_level_exp (level, experience)        -- 等级经验分析
);-- 生产环境游戏查询场景
-- 1. 玩家登录验证(每秒数万次)
SELECT player_id, player_uuid, level, server_id, player_status
FROM game_players 
WHERE username = 'player123' AND player_status = 1;  -- 使用 idx_username-- 2. 服务器等级排行榜(游戏内排行榜系统)
SELECT player_id, username, level, experience
FROM game_players 
WHERE server_id = 1001 AND player_status = 1
ORDER BY level DESC, experience DESC LIMIT 100;  -- 使用 idx_server_level-- 3. 公会成员管理(公会系统)
SELECT player_id, username, level, last_login_time, total_playtime
FROM game_players 
WHERE guild_id = 12345 AND player_status = 1
ORDER BY level DESC;  -- 使用 idx_guild_level-- 4. VIP用户分析(运营分析)
SELECT vip_level,COUNT(*) as player_count,AVG(level) as avg_level,SUM(diamond) as total_diamond
FROM game_players 
WHERE player_status = 1
GROUP BY vip_level
ORDER BY vip_level DESC;  -- 使用 idx_vip_level-- 5. 玩家流失分析(运营重点关注)
SELECT DATE(last_login_time) as last_login_date,COUNT(*) as player_count
FROM game_players 
WHERE last_login_time < DATE_SUB(NOW(), INTERVAL 7 DAY)
AND register_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)  -- 30天内注册但7天未登录
GROUP BY DATE(last_login_time)
ORDER BY last_login_date DESC;  -- 使用 idx_login_time
游戏充值记录表
-- 游戏充值记录表(亿级交易数据)
CREATE TABLE game_payments (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,时间序列payment_id VARCHAR(32) UNIQUE,                 -- 支付订单号player_id BIGINT,                              -- 玩家IDserver_id INT,                                 -- 服务器IDproduct_id VARCHAR(20),                        -- 商品IDproduct_name VARCHAR(100),                     -- 商品名称payment_amount DECIMAL(10,2),                  -- 支付金额(人民币)diamond_amount INT,                            -- 获得钻石数量payment_channel TINYINT,                       -- 支付渠道:1微信 2支付宝 3苹果 4谷歌payment_status TINYINT,                        -- 支付状态:1待支付 2已支付 3已发货 4失败 5退款payment_time TIMESTAMP,                        -- 支付完成时间device_type TINYINT,                           -- 设备类型:1iOS 2Android 3PCclient_version VARCHAR(20),                    -- 客户端版本created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,-- 充值分析索引INDEX idx_payment_id (payment_id),             -- 支付订单查询INDEX idx_player_status (player_id, payment_status), -- 玩家充值记录INDEX idx_server_time (server_id, payment_time), -- 服务器收入统计INDEX idx_product_time (product_id, payment_time), -- 商品销售分析INDEX idx_channel_amount (payment_channel, payment_amount), -- 渠道收入分析INDEX idx_status_time (payment_status, payment_time), -- 支付状态监控INDEX idx_device_time (device_type, payment_time)  -- 设备收入统计
);-- 游戏充值查询场景
-- 1. 玩家充值历史(客服查询)
SELECT payment_id,product_name,payment_amount,diamond_amount,payment_status,payment_time
FROM game_payments 
WHERE player_id = 123456 
ORDER BY payment_time DESC LIMIT 50;  -- 使用 idx_player_status-- 2. 服务器日收入统计(运营日报)
SELECT DATE(payment_time) as pay_date,COUNT(*) as order_count,SUM(payment_amount) as total_revenue,AVG(payment_amount) as avg_amount
FROM game_payments 
WHERE server_id = 1001 
AND payment_status = 2  -- 已支付
AND payment_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY DATE(payment_time)
ORDER BY pay_date DESC;  -- 使用 idx_server_time-- 3. 商品销售排行(商品运营分析)
SELECT product_id,product_name,COUNT(*) as sale_count,SUM(payment_amount) as total_revenue
FROM game_payments 
WHERE payment_status = 2
AND payment_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY product_id, product_name
ORDER BY total_revenue DESC LIMIT 20;  -- 使用 idx_product_time-- 4. 支付渠道分析(财务分析)
SELECT payment_channel,device_type,COUNT(*) as transaction_count,SUM(payment_amount) as channel_revenue,AVG(payment_amount) as avg_transaction
FROM game_payments 
WHERE payment_status = 2
AND payment_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY payment_channel, device_type;  -- 使用 idx_channel_amount

8. 直播平台系统

直播间数据表
-- 直播间数据表(百万级直播间)
CREATE TABLE live_rooms (room_id BIGINT AUTO_INCREMENT PRIMARY KEY,     -- 聚集索引,直播间IDroom_number VARCHAR(20) UNIQUE,                -- 直播间号码,对外展示streamer_id BIGINT,                            -- 主播IDroom_title VARCHAR(200),                       -- 直播间标题category_id INT,                               -- 直播分类IDroom_status TINYINT,                           -- 直播状态:1直播中 2暂停 3关闭viewer_count INT DEFAULT 0,                    -- 当前观看人数max_viewer_count INT DEFAULT 0,                -- 历史最高人数total_duration INT DEFAULT 0,                  -- 累计直播时长(分钟)gift_total_value DECIMAL(15,2) DEFAULT 0,      -- 礼物总价值follower_count INT DEFAULT 0,                  -- 关注数room_quality TINYINT DEFAULT 1,                -- 画质:1流畅 2高清 3超清 4蓝光is_recommended TINYINT DEFAULT 0,              -- 是否推荐:0否 1是start_time TIMESTAMP,                          -- 开播时间end_time TIMESTAMP,                            -- 关播时间created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 直播业务索引INDEX idx_room_number (room_number),           -- 直播间号码查询INDEX idx_streamer_status (streamer_id, room_status), -- 主播直播管理INDEX idx_category_status (category_id, room_status), -- 分类直播列表INDEX idx_status_viewer (room_status, viewer_count),  -- 热门直播排序INDEX idx_recommended_viewer (is_recommended, viewer_count), -- 推荐直播INDEX idx_gift_value (gift_total_value),        -- 收入排行INDEX idx_start_time (start_time)               -- 开播时间分析
);-- 生产环境直播查询场景
-- 1. 直播间首页(用户进入直播间)
SELECT room_id,room_title,streamer_id,viewer_count,room_status,start_time
FROM live_rooms 
WHERE room_number = '123456' AND room_status = 1;  -- 使用 idx_room_number-- 2. 热门直播列表(直播首页推荐)
SELECT room_id,room_number,room_title,streamer_id,viewer_count,category_id
FROM live_rooms 
WHERE room_status = 1  -- 正在直播
ORDER BY viewer_count DESC, is_recommended DESC LIMIT 50;  -- 使用 idx_status_viewer-- 3. 分类直播列表(用户按分类浏览)
SELECT room_id,room_number,room_title,viewer_count,gift_total_value
FROM live_rooms 
WHERE category_id = 101 AND room_status = 1
ORDER BY viewer_count DESC LIMIT 30;  -- 使用 idx_category_status-- 4. 主播收入排行榜(周榜月榜)
SELECT room_id,room_number,streamer_id,gift_total_value,viewer_count
FROM live_rooms 
WHERE start_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)  -- 本周数据
ORDER BY gift_total_value DESC LIMIT 100;  -- 使用 idx_gift_value-- 5. 推荐直播算法(个性化推荐)
SELECT room_id,room_number,room_title,viewer_count,category_id
FROM live_rooms 
WHERE is_recommended = 1 
AND room_status = 1
AND viewer_count >= 100  -- 有一定人气的直播间
ORDER BY viewer_count DESC, RAND() LIMIT 20;  -- 使用 idx_recommended_viewer
直播礼物记录表
-- 直播礼物记录表(十亿级数据)
CREATE TABLE live_gifts (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,时间序列gift_id VARCHAR(32) UNIQUE,                    -- 礼物记录IDroom_id BIGINT,                                -- 直播间IDstreamer_id BIGINT,                            -- 主播IDuser_id BIGINT,                                -- 送礼用户IDgift_type_id INT,                              -- 礼物类型IDgift_name VARCHAR(50),                         -- 礼物名称gift_count INT,                                -- 礼物数量unit_price DECIMAL(8,2),                       -- 单价(人民币)total_value DECIMAL(10,2),                     -- 总价值gift_level TINYINT,                            -- 礼物等级:1普通 2精品 3豪华 4传说is_combo TINYINT DEFAULT 0,                    -- 是否连击:0否 1是combo_count INT DEFAULT 1,                     -- 连击次数platform_commission DECIMAL(8,2),              -- 平台抽成streamer_income DECIMAL(8,2),                  -- 主播收入gift_time TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3), -- 送礼时间-- 礼物分析索引INDEX idx_gift_id (gift_id),                   -- 礼物记录查询INDEX idx_room_time (room_id, gift_time),      -- 直播间礼物统计INDEX idx_streamer_time (streamer_id, gift_time), -- 主播收入统计INDEX idx_user_time (user_id, gift_time),      -- 用户消费记录INDEX idx_type_time (gift_type_id, gift_time), -- 礼物类型分析INDEX idx_value_time (total_value, gift_time), -- 大额礼物监控INDEX idx_level_time (gift_level, gift_time)   -- 礼物等级统计
);-- 直播礼物查询场景
-- 1. 直播间实时礼物流水(直播间礼物动画)
SELECT user_id,gift_name,gift_count,total_value,is_combo,gift_time
FROM live_gifts 
WHERE room_id = 123456 
AND gift_time >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)
ORDER BY gift_time DESC LIMIT 100;  -- 使用 idx_room_time-- 2. 主播收入统计(主播后台)
SELECT DATE(gift_time) as gift_date,COUNT(*) as gift_count,SUM(total_value) as total_revenue,SUM(streamer_income) as streamer_revenue,AVG(total_value) as avg_gift_value
FROM live_gifts 
WHERE streamer_id = 789012 
AND gift_time >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY DATE(gift_time)
ORDER BY gift_date DESC;  -- 使用 idx_streamer_time-- 3. 用户消费记录(用户个人中心)
SELECT room_id,streamer_id,gift_name,gift_count,total_value,gift_time
FROM live_gifts 
WHERE user_id = 456789 
ORDER BY gift_time DESC LIMIT 50;  -- 使用 idx_user_time-- 4. 土豪用户识别(运营分析)
SELECT user_id,COUNT(*) as gift_times,SUM(total_value) as total_spent,AVG(total_value) as avg_gift_value,MAX(total_value) as max_single_gift
FROM live_gifts 
WHERE gift_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY user_id
HAVING total_spent >= 1000.00  -- 一周消费超过1000元
ORDER BY total_spent DESC LIMIT 100;  -- 使用 idx_user_time-- 5. 平台礼物收入分析(财务分析)
SELECT gift_type_id,gift_name,SUM(gift_count) as total_sent,SUM(total_value) as total_revenue,SUM(platform_commission) as platform_income
FROM live_gifts 
WHERE gift_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY gift_type_id, gift_name
ORDER BY total_revenue DESC;  -- 使用 idx_type_time

9. 政府公共服务系统

政务服务办件表
-- 政务服务办件表(千万级办件数据)
CREATE TABLE government_applications (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,按时间自增application_no VARCHAR(30) UNIQUE,             -- 办件编号,对外展示service_code VARCHAR(20),                      -- 服务事项编码service_name VARCHAR(200),                     -- 服务事项名称applicant_id_card VARCHAR(18),                 -- 申请人身份证号applicant_name VARCHAR(50),                    -- 申请人姓名applicant_phone VARCHAR(20),                   -- 申请人手机号enterprise_code VARCHAR(20),                   -- 企业统一社会信用代码(企业办件)department_code VARCHAR(10),                   -- 受理部门编码window_code VARCHAR(10),                       -- 受理窗口编码staff_id VARCHAR(20),                          -- 受理工作人员IDapplication_type TINYINT,                      -- 申请类型:1个人 2企业urgency_level TINYINT DEFAULT 2,               -- 紧急程度:1加急 2普通 3延期current_status TINYINT,                        -- 当前状态:1已受理 2审核中 3补正 4办结 5终止legal_time_limit INT,                          -- 法定办结时限(工作日)promised_time_limit INT,                       -- 承诺办结时限(工作日)actual_time_limit INT,                         -- 实际办结时限(工作日)is_overdue TINYINT DEFAULT 0,                  -- 是否超期:0未超期 1超期application_date DATE,                         -- 申请日期accept_date DATE,                              -- 受理日期finish_date DATE,                              -- 办结日期created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 政务查询索引INDEX idx_application_no (application_no),     -- 办件编号查询(用户查询进度)INDEX idx_applicant_id (applicant_id_card),    -- 身份证号查询(个人办件)INDEX idx_enterprise_code (enterprise_code),   -- 企业代码查询(企业办件)INDEX idx_department_status (department_code, current_status), -- 部门办件管理INDEX idx_service_date (service_code, application_date),       -- 服务事项统计INDEX idx_staff_status (staff_id, current_status),            -- 工作人员工作量INDEX idx_status_overdue (current_status, is_overdue),        -- 超期办件监控INDEX idx_urgency_date (urgency_level, application_date)      -- 加急办件处理
);-- 生产环境政务查询场景
-- 1. 用户查询办件进度(政务APP/网站最常用功能)
SELECT application_no,service_name,current_status,promised_time_limit,accept_date,finish_date,CASE current_statusWHEN 1 THEN '已受理'WHEN 2 THEN '审核中'WHEN 3 THEN '需补正材料'WHEN 4 THEN '已办结'WHEN 5 THEN '已终止'END as status_name
FROM government_applications 
WHERE applicant_id_card = '110101199001011234'  -- 用户身份证号
AND application_date >= DATE_SUB(CURDATE(), INTERVAL 365 DAY)  -- 一年内的办件
ORDER BY created_at DESC;  -- 使用 idx_applicant_id-- 2. 部门办件管理(政务工作人员工作台)
SELECT current_status,COUNT(*) as count,COUNT(CASE WHEN is_overdue = 1 THEN 1 END) as overdue_count,AVG(actual_time_limit) as avg_time_limit
FROM government_applications 
WHERE department_code = 'DEPT001'
AND application_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY current_status;  -- 使用 idx_department_status-- 3. 超期办件预警(每日定时检查)
SELECT application_no,service_name,applicant_name,staff_id,promised_time_limit,DATEDIFF(CURDATE(), accept_date) as elapsed_days
FROM government_applications 
WHERE current_status IN (1, 2, 3)  -- 未办结
AND is_overdue = 0  -- 尚未标记超期
AND DATEDIFF(CURDATE(), accept_date) >= promised_time_limit
ORDER BY elapsed_days DESC;  -- 使用 idx_status_overdue
网约车出行平台
-- 网约车订单表(日订单量千万级)
CREATE TABLE ride_orders (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引,订单时间序列order_no VARCHAR(32) UNIQUE,                   -- 订单号,对外展示passenger_id BIGINT,                           -- 乘客IDdriver_id BIGINT,                              -- 司机ID(接单后分配)vehicle_id BIGINT,                             -- 车辆IDservice_type TINYINT,                          -- 服务类型:1快车 2专车 3豪华车 4拼车order_status TINYINT,                          -- 订单状态:1待接单 2已接单 3服务中 4已完成 5已取消start_longitude DECIMAL(10,6),                 -- 起点经度start_latitude DECIMAL(10,6),                  -- 起点纬度start_address VARCHAR(500),                    -- 起点地址end_longitude DECIMAL(10,6),                   -- 终点经度end_latitude DECIMAL(10,6),                    -- 终点纬度end_address VARCHAR(500),                      -- 终点地址city_code VARCHAR(10),                         -- 城市编码estimated_distance DECIMAL(8,2),               -- 预估距离(公里)actual_distance DECIMAL(8,2),                  -- 实际距离(公里)estimated_duration INT,                        -- 预估时长(分钟)actual_duration INT,                           -- 实际时长(分钟)estimated_amount DECIMAL(10,2),                -- 预估费用actual_amount DECIMAL(10,2),                   -- 实际费用created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 下单时间accepted_at TIMESTAMP,                         -- 接单时间started_at TIMESTAMP,                          -- 开始服务时间completed_at TIMESTAMP,                        -- 完成时间-- 核心业务索引INDEX idx_order_no (order_no),                 -- 订单号查询INDEX idx_passenger_status (passenger_id, order_status), -- 乘客订单历史INDEX idx_driver_status (driver_id, order_status),       -- 司机订单管理INDEX idx_city_status_time (city_code, order_status, created_at), -- 城市运营分析INDEX idx_status_created (order_status, created_at),     -- 订单状态分析INDEX idx_service_type_time (service_type, created_at),  -- 服务类型统计INDEX idx_location_time (city_code, start_longitude, start_latitude, created_at) -- 热点区域分析
);-- 生产环境网约车查询场景
-- 1. 乘客查询历史订单(乘客APP)
SELECT order_no,service_type,start_address,end_address,actual_amount,order_status,created_at,completed_at
FROM ride_orders 
WHERE passenger_id = 123456 
AND order_status IN (4, 5)  -- 已完成或已取消
ORDER BY created_at DESC LIMIT 20;  -- 使用 idx_passenger_status-- 2. 城市运营实时监控(运营中心大屏)
SELECT city_code,service_type,COUNT(*) as total_orders,COUNT(CASE WHEN order_status = 1 THEN 1 END) as waiting_orders,COUNT(CASE WHEN order_status = 4 THEN 1 END) as completed_orders,AVG(CASE WHEN actual_amount > 0 THEN actual_amount END) as avg_amount,AVG(CASE WHEN actual_duration > 0 THEN actual_duration END) as avg_duration
FROM ride_orders 
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR)  -- 最近1小时
GROUP BY city_code, service_type;  -- 使用 idx_city_status_time-- 3. 热点区域分析(智能调度算法)
SELECT ROUND(start_longitude, 3) as lng_area,ROUND(start_latitude, 3) as lat_area,COUNT(*) as order_count,AVG(estimated_amount) as avg_amount
FROM ride_orders 
WHERE city_code = 'BJ'
AND created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR)
AND created_at < DATE_SUB(NOW(), INTERVAL 1 HOUR)  -- 前一小时的数据
GROUP BY ROUND(start_longitude, 3), ROUND(start_latitude, 3)
HAVING order_count >= 5  -- 订单密度较高的区域
ORDER BY order_count DESC;  -- 使用 idx_location_time

10. 生产环境性能优化实战

电商订单表优化案例
-- 原始设计(性能问题)
CREATE TABLE orders_old (id BIGINT AUTO_INCREMENT PRIMARY KEY,order_no VARCHAR(32),  -- 没有索引,订单号查询慢user_id BIGINT,        -- 没有复合索引,用户订单列表查询慢status TINYINT,created_at TIMESTAMP,INDEX idx_user_id (user_id)  -- 单列索引,不够优化
);-- 优化后设计
CREATE TABLE orders_optimized (id BIGINT AUTO_INCREMENT PRIMARY KEY,          -- 聚集索引保持不变order_no VARCHAR(32),                          user_id BIGINT,                                status TINYINT,                                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,-- 优化索引设计UNIQUE KEY uk_order_no (order_no),             -- 订单号唯一索引INDEX idx_user_status_time (user_id, status, created_at), -- 复合索引优化用户订单查询INDEX idx_status_time (status, created_at),    -- 管理后台按状态查询INDEX idx_created_time (created_at)             -- 时间范围统计
);-- 性能对比
-- 查询用户订单列表(优化前后对比)
-- 优化前:需要回表,性能差
SELECT * FROM orders_old WHERE user_id = 123456 ORDER BY created_at DESC LIMIT 20;-- 优化后:使用覆盖索引,性能大幅提升
SELECT id, order_no, status, created_at 
FROM orders_optimized 
WHERE user_id = 123456 AND status IN (1,2,3,4)
ORDER BY created_at DESC LIMIT 20;
-- 执行计划:Using index(覆盖索引,无需回表)
分表分库策略
-- 大表拆分策略(日订单量百万级)
-- 按时间分表
CREATE TABLE orders_202412 (id BIGINT AUTO_INCREMENT PRIMARY KEY,order_no VARCHAR(32) UNIQUE,user_id BIGINT,status TINYINT,created_at TIMESTAMP,INDEX idx_user_status (user_id, status),INDEX idx_status_time (status, created_at)
) PARTITION BY RANGE (TO_DAYS(created_at)) (PARTITION p20241201 VALUES LESS THAN (TO_DAYS('2024-12-02')),PARTITION p20241202 VALUES LESS THAN (TO_DAYS('2024-12-03')),-- ... 按日分区
);-- 按用户ID分库分表(水平拆分)
-- 订单表_0, 订单表_1, 订单表_2, 订单表_3 (根据 user_id % 4)
CREATE TABLE orders_0 (id BIGINT AUTO_INCREMENT PRIMARY KEY,order_no VARCHAR(32) UNIQUE,user_id BIGINT,  -- user_id % 4 = 0 的数据status TINYINT,created_at TIMESTAMP,INDEX idx_user_status_time (user_id, status, created_at)
);-- 应用层路由逻辑
-- 写入:根据 user_id % 4 决定写入哪个分表
-- 查询:根据 user_id % 4 决定查询哪个分表
实际生产问题解决案例
案例1:电商订单查询优化(某电商平台实战)
-- 【问题背景】
-- 电商平台用户订单查询页面响应时间超过5秒,用户体验极差
-- 订单表:orders,数据量2亿条,每日新增100万订单
-- 主要查询:用户查看自己的订单列表-- 【原始设计】(存在严重性能问题)
CREATE TABLE orders_before (id BIGINT AUTO_INCREMENT PRIMARY KEY,      -- 聚集索引order_no VARCHAR(32),                      -- 订单号(无索引!)user_id BIGINT,                            -- 用户IDstatus TINYINT,                            -- 订单状态total_amount DECIMAL(15,2),                -- 订单金额created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,INDEX idx_user_id (user_id)                -- 单列索引,不够优化
);-- 【问题SQL】(执行时间:3-8秒)
SELECT * FROM orders_before 
WHERE user_id = 123456 
ORDER BY created_at DESC LIMIT 20;
-- 执行计划:Using filesort, 需要排序大量数据-- 【优化后设计】
CREATE TABLE orders_after (id BIGINT AUTO_INCREMENT PRIMARY KEY,      -- 聚集索引保持不变order_no VARCHAR(32),                      user_id BIGINT,                            status TINYINT,                            total_amount DECIMAL(15,2),                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 关键优化:复合索引UNIQUE KEY uk_order_no (order_no),         -- 订单号唯一索引INDEX idx_user_time (user_id, created_at), -- 用户+时间复合索引INDEX idx_user_status_time (user_id, status, created_at) -- 覆盖更多查询场景
);-- 【优化后SQL】(执行时间:50ms)
SELECT * FROM orders_after 
WHERE user_id = 123456 
ORDER BY created_at DESC LIMIT 20;
-- 执行计划:Using index for order-by, 直接利用索引顺序-- 【优化效果】
-- 响应时间:从5秒降低到50ms,提升100倍
-- CPU使用率:从80%降低到5%
-- 用户满意度:显著提升,投诉减少90%
案例2:社交应用朋友圈优化(某社交APP实战)
-- 【问题背景】
-- 朋友圈时间线加载缓慢,用户刷新朋友圈需要等待10秒以上
-- 用户动态表:user_posts,数据量10亿条
-- 主要查询:获取用户关注的人的最新动态-- 【原始设计】(查询超时)
CREATE TABLE user_posts_before (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            -- 发布者IDcontent TEXT,                              -- 动态内容created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,INDEX idx_user_id (user_id),               -- 单列索引INDEX idx_created_at (created_at)          -- 时间索引
);-- 【问题SQL】(执行时间:超时)
-- 查询关注用户的动态(朋友圈feed流)
SELECT p.* FROM user_posts_before p
WHERE p.user_id IN (SELECT following_id FROM user_follows WHERE follower_id = 123456 AND status = 1
)
ORDER BY p.created_at DESC LIMIT 50;
-- 问题:IN查询 + 大表排序,性能极差-- 【优化方案1:索引优化】
CREATE TABLE user_posts_v1 (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            content TEXT,                              created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,is_deleted TINYINT DEFAULT 0,              -- 软删除标记-- 优化索引设计INDEX idx_user_time (user_id, created_at), -- 复合索引,支持按用户时间排序INDEX idx_time_user (created_at, user_id), -- 反向索引,支持全局时间排序INDEX idx_user_status (user_id, is_deleted) -- 过滤删除的动态
);-- 优化后SQL v1(执行时间:2秒)
SELECT p.* FROM user_posts_v1 p
INNER JOIN user_follows f ON p.user_id = f.following_id
WHERE f.follower_id = 123456 AND f.status = 1 AND p.is_deleted = 0
ORDER BY p.created_at DESC LIMIT 50;
-- 使用JOIN替代IN查询,性能有所改善-- 【优化方案2:推送模式(最终方案)】
-- 创建用户时间线表,预先计算好每个用户的朋友圈内容
CREATE TABLE user_timeline (id BIGINT AUTO_INCREMENT PRIMARY KEY,     -- 聚集索引user_id BIGINT,                           -- 接收动态的用户IDpost_id BIGINT,                           -- 动态IDauthor_id BIGINT,                         -- 动态作者IDpost_time TIMESTAMP,                      -- 动态发布时间created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 推送时间-- 专门为时间线查询优化的索引INDEX idx_user_posttime (user_id, post_time), -- 用户时间线主索引INDEX idx_user_created (user_id, created_at)  -- 备用排序索引
);-- 【终极优化SQL】(执行时间:20ms)
SELECT t.post_id, t.author_id, t.post_time 
FROM user_timeline t
WHERE t.user_id = 123456 
ORDER BY t.post_time DESC LIMIT 50;
-- 直接查询预计算的时间线,性能极佳-- 【优化效果】
-- 响应时间:从10秒以上降低到20ms,提升500倍
-- 架构改进:从拉取模式改为推送模式
-- 存储成本:增加30%,但用户体验大幅提升
-- 系统稳定性:显著提升,高峰期不再卡顿
案例3:金融风控系统优化(某支付公司实战)
-- 【问题背景】
-- 实时风控系统响应慢,大额交易预警延迟严重
-- 交易表:payment_records,数据量50亿条,QPS峰值10万
-- 关键需求:100ms内完成风控检查-- 【原始设计】(风控查询超时)
CREATE TABLE payment_records_before (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            -- 用户IDamount DECIMAL(15,2),                      -- 交易金额payment_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,merchant_id BIGINT,                        -- 商户IDstatus TINYINT,                            -- 支付状态INDEX idx_user_id (user_id),               -- 基础索引INDEX idx_amount (amount),                 -- 金额索引INDEX idx_time (payment_time)              -- 时间索引
);-- 【问题SQL】(执行时间:3-10秒)
-- 风控检查:用户最近1小时大额交易次数
SELECT COUNT(*) FROM payment_records_before 
WHERE user_id = 123456 
AND amount >= 10000.00 
AND payment_time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND status = 2;  -- 成功交易
-- 问题:需要扫描大量数据,索引效率低-- 【优化方案:针对风控查询设计索引】
CREATE TABLE payment_records_optimized (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            amount DECIMAL(15,2),                      payment_time TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3), -- 毫秒精度merchant_id BIGINT,                        status TINYINT,                            risk_level TINYINT DEFAULT 0,              -- 风险等级:0正常 1可疑 2高危-- 针对风控优化的复合索引INDEX idx_user_status_time (user_id, status, payment_time), -- 用户交易时间线INDEX idx_user_amount_time (user_id, amount, payment_time), -- 用户金额时间索引INDEX idx_amount_time_status (amount, payment_time, status), -- 大额交易监控INDEX idx_risk_time (risk_level, payment_time),             -- 风险交易分析INDEX idx_merchant_amount (merchant_id, amount, payment_time) -- 商户大额交易
);-- 【优化后SQL】(执行时间:5ms)
-- 风控检查优化版本
SELECT COUNT(*) FROM payment_records_optimized 
WHERE user_id = 123456 
AND status = 2
AND payment_time >= DATE_SUB(NOW(3), INTERVAL 1 HOUR)
AND amount >= 10000.00;
-- 使用 idx_user_status_time + 覆盖查询,性能大幅提升-- 【进一步优化:实时风控缓存表】
CREATE TABLE user_risk_profile (user_id BIGINT PRIMARY KEY,               -- 聚集索引last_hour_count INT DEFAULT 0,            -- 最近1小时交易次数last_hour_amount DECIMAL(15,2) DEFAULT 0, -- 最近1小时交易总额last_day_count INT DEFAULT 0,             -- 最近24小时交易次数last_day_amount DECIMAL(15,2) DEFAULT 0,  -- 最近24小时交易总额risk_score INT DEFAULT 0,                 -- 风险评分last_update TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3), -- 最后更新时间INDEX idx_risk_score (risk_score),        -- 风险评分索引INDEX idx_last_update (last_update)       -- 更新时间索引
);-- 【实时风控查询】(执行时间:<1ms)
SELECT risk_score, last_hour_count, last_hour_amount 
FROM user_risk_profile 
WHERE user_id = 123456;
-- 直接查询预计算的风控数据,响应极快-- 【优化效果】
-- 响应时间:从3-10秒降低到1ms,提升3000-10000倍
-- 风控准确性:实时更新,误报率降低60%
-- 系统吞吐量:支持QPS从1000提升到10万
-- 业务影响:大幅减少用户交易被误拦截的情况
案例4:视频网站播放记录优化(某视频平台实战)
-- 【问题背景】
-- 用户观看历史查询慢,推荐算法计算超时
-- 播放记录表:video_plays,数据量100亿条,日增量5000万
-- 核心需求:快速获取用户观看偏好,支持推荐算法-- 【原始设计】(查询缓慢)
CREATE TABLE video_plays_before (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            -- 用户IDvideo_id BIGINT,                           -- 视频IDplay_duration INT,                         -- 播放时长(秒)video_duration INT,                        -- 视频总时长completion_rate DECIMAL(5,2),              -- 完播率play_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,device_type TINYINT,                       -- 设备类型INDEX idx_user_id (user_id),               -- 单列索引INDEX idx_video_id (video_id),             -- 单列索引INDEX idx_play_time (play_time)            -- 时间索引
);-- 【问题SQL】(执行时间:30秒+)
-- 推荐算法:获取用户最近观看的视频类型偏好
SELECT v.category_id, COUNT(*) as watch_count, AVG(p.completion_rate) as avg_completion
FROM video_plays_before p
JOIN videos v ON p.video_id = v.video_id
WHERE p.user_id = 123456 
AND p.play_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
AND p.completion_rate >= 0.6  -- 有效观看
GROUP BY v.category_id
ORDER BY watch_count DESC;
-- 问题:大表JOIN + 复杂聚合,性能极差-- 【优化方案:数据预聚合 + 专用索引】
-- 用户观看偏好汇总表
CREATE TABLE user_watch_preferences (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            -- 用户IDcategory_id INT,                           -- 视频分类IDwatch_count INT DEFAULT 0,                 -- 观看次数total_duration INT DEFAULT 0,              -- 总观看时长avg_completion_rate DECIMAL(5,2) DEFAULT 0, -- 平均完播率last_watch_time TIMESTAMP,                 -- 最后观看时间preference_score DECIMAL(8,4) DEFAULT 0,   -- 偏好评分stats_date DATE,                           -- 统计日期-- 推荐算法专用索引UNIQUE KEY uk_user_category_date (user_id, category_id, stats_date),INDEX idx_user_score (user_id, preference_score), -- 用户偏好排序INDEX idx_user_lastwatch (user_id, last_watch_time), -- 最近观看INDEX idx_category_score (category_id, preference_score) -- 分类热度
);-- 优化后的播放记录表
CREATE TABLE video_plays_optimized (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT,                            video_id BIGINT,                           category_id INT,                           -- 冗余字段,避免JOINplay_duration INT,                         video_duration INT,                        completion_rate DECIMAL(5,2),              play_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,device_type TINYINT,                       -- 针对不同查询场景的索引INDEX idx_user_time (user_id, play_time),  -- 用户观看历史INDEX idx_user_category_time (user_id, category_id, play_time), -- 用户分类偏好INDEX idx_video_time (video_id, play_time), -- 视频播放统计INDEX idx_completion_user (completion_rate, user_id), -- 完播率分析INDEX idx_category_time (category_id, play_time) -- 分类热度统计
);-- 【优化后SQL】(执行时间:10ms)
-- 推荐算法优化版本
SELECT category_id, preference_score, watch_count, avg_completion_rate
FROM user_watch_preferences 
WHERE user_id = 123456 
AND stats_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
ORDER BY preference_score DESC LIMIT 10;
-- 直接查询预聚合数据,性能极佳-- 【实时观看行为分析】(执行时间:50ms)
SELECT category_id,COUNT(*) as recent_watches,AVG(completion_rate) as avg_completion
FROM video_plays_optimized 
WHERE user_id = 123456 
AND play_time >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY category_id;
-- 使用优化索引,快速获取实时数据-- 【优化效果】
-- 推荐算法响应时间:从30秒降低到10ms,提升3000倍
-- 用户观看历史加载:从5秒降低到100ms,提升50倍
-- 推荐准确率:提升25%,用户停留时间增加40%
-- 服务器资源:CPU使用率降低70%,支持更多并发用户
案例5:电商库存系统优化(某大型电商实战)
-- 【问题背景】
-- 商品库存查询和更新性能问题,高并发下出现死锁
-- 库存表:product_inventory,数据量5000万条
-- 关键需求:高并发库存扣减,实时库存查询-- 【原始设计】(高并发死锁)
CREATE TABLE product_inventory_before (id BIGINT AUTO_INCREMENT PRIMARY KEY,product_id BIGINT,                         -- 商品IDwarehouse_id INT,                          -- 仓库IDavailable_stock INT,                       -- 可用库存reserved_stock INT DEFAULT 0,              -- 预占库存total_stock INT,                           -- 总库存updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,UNIQUE KEY uk_product_warehouse (product_id, warehouse_id),INDEX idx_product_id (product_id)          -- 基础索引
);-- 【问题SQL】(高并发死锁)
-- 库存扣减操作
UPDATE product_inventory_before 
SET available_stock = available_stock - 1,reserved_stock = reserved_stock + 1
WHERE product_id = 12345 AND warehouse_id = 1 AND available_stock >= 1;
-- 问题:表级锁竞争,高并发下频繁死锁-- 【优化方案1:分库分表 + 索引优化】
-- 按商品ID哈希分表,减少锁竞争
CREATE TABLE product_inventory_0 (  -- product_id % 10 = 0id BIGINT AUTO_INCREMENT PRIMARY KEY,product_id BIGINT,                         warehouse_id INT,                          available_stock INT,                       reserved_stock INT DEFAULT 0,              total_stock INT,                           version INT DEFAULT 0,                     -- 乐观锁版本号updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,-- 优化索引设计UNIQUE KEY uk_product_warehouse (product_id, warehouse_id),INDEX idx_warehouse_product (warehouse_id, product_id), -- 仓库维度查询INDEX idx_stock_product (available_stock, product_id)   -- 库存预警
);-- 【优化方案2:乐观锁 + 批量操作】
-- 使用乐观锁避免死锁
UPDATE product_inventory_0 
SET available_stock = available_stock - 1,reserved_stock = reserved_stock + 1,version = version + 1
WHERE product_id = 12345 
AND warehouse_id = 1 
AND available_stock >= 1 
AND version = @old_version;  -- 乐观锁检查-- 【优化方案3:库存缓存表】
-- 高频查询商品的库存缓存
CREATE TABLE hot_product_stock (product_id BIGINT PRIMARY KEY,             -- 聚集索引total_available INT DEFAULT 0,             -- 全部仓库可用总库存update_frequency INT DEFAULT 0,            -- 更新频率统计last_update TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3),INDEX idx_available (total_available),     -- 库存查询索引INDEX idx_frequency (update_frequency)     -- 热度排序
);-- 【优化后查询】(执行时间:1ms)
-- 快速库存检查
SELECT total_available FROM hot_product_stock WHERE product_id = 12345;-- 【库存分布查询】(执行时间:5ms)
-- 查看商品在各仓库的库存分布
SELECT warehouse_id, available_stock, reserved_stock
FROM product_inventory_0  -- 根据product_id路由到正确分表
WHERE product_id = 12345 
ORDER BY available_stock DESC;-- 【优化效果】
-- 并发性能:支持QPS从1000提升到50000
-- 死锁率:从每小时100次降低到每天不到5次
-- 查询响应时间:从100ms降低到1-5ms
-- 库存准确率:99.99%,误差大幅降低
-- 系统稳定性:高峰期不再出现库存系统崩溃
true

最佳实践建议

1. 聚集索引设计原则

选择合适的聚集索引键
-- ✅ 好的选择:自增主键
CREATE TABLE orders (id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 单调递增,避免页分裂user_id INT,product_id INT,order_time TIMESTAMP
);-- ❌ 避免:UUID作为聚集索引
CREATE TABLE bad_orders (uuid CHAR(36) PRIMARY KEY,  -- 随机值,会导致频繁页分裂user_id INT,product_id INT
);-- ✅ 如果必须使用UUID,考虑有序UUID
-- 或者使用自增ID + UUID的组合方案
CREATE TABLE better_orders (id BIGINT AUTO_INCREMENT PRIMARY KEY,uuid CHAR(36) UNIQUE,user_id INT,product_id INT
);
避免更新聚集索引键
-- ❌ 避免更新主键
UPDATE users SET id = 999 WHERE id = 1;-- ✅ 使用业务无关的自增ID
CREATE TABLE users (id BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 永不更新user_uuid CHAR(36) UNIQUE,             -- 业务相关的唯一标识username VARCHAR(50),email VARCHAR(100)
);

2. 非聚集索引优化策略

创建复合索引
-- 根据查询模式创建复合索引
-- 遵循"等值查询在前,范围查询在后"的原则
CREATE INDEX idx_user_status_time ON orders(user_id, status, created_at);-- 支持的查询模式
SELECT * FROM orders WHERE user_id = 1;                                    -- 使用索引
SELECT * FROM orders WHERE user_id = 1 AND status = 2;                     -- 使用索引
SELECT * FROM orders WHERE user_id = 1 AND status = 2 AND created_at > '2024-01-01'; -- 使用索引
SELECT * FROM orders WHERE user_id = 1 AND created_at > '2024-01-01';      -- 部分使用索引-- 不支持的查询模式
SELECT * FROM orders WHERE status = 2;                                      -- 不使用索引
SELECT * FROM orders WHERE created_at > '2024-01-01';                       -- 不使用索引
利用覆盖索引
-- 设计覆盖索引减少回表
CREATE INDEX idx_user_summary ON orders(user_id, status, order_amount, created_at);-- 这个查询可以完全由索引覆盖
SELECT user_id, COUNT(*) as order_count, SUM(order_amount) as total_amount
FROM orders 
WHERE user_id = 1 AND status IN (1, 2)
GROUP BY user_id;
索引维护策略
-- 定期分析索引使用情况
SELECT object_schema,object_name,index_name,count_read,count_write,count_fetch,count_insert,count_update,count_delete
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE object_schema = 'your_database'
ORDER BY count_read DESC;-- 删除未使用的索引
-- ALTER TABLE table_name DROP INDEX unused_index_name;

3. 性能监控与调优

监控索引效率
-- 检查慢查询
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;-- 分析执行计划
EXPLAIN FORMAT=JSON 
SELECT * FROM users WHERE email = 'test@example.com';-- 监控索引统计信息
SHOW INDEX FROM users;
ANALYZE TABLE users;
索引碎片整理
-- 检查表碎片
SELECT table_name,ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)',ROUND((data_free / 1024 / 1024), 2) AS 'Free Space (MB)',ROUND((data_free / (data_length + index_length) * 100), 2) AS 'Fragmentation %'
FROM information_schema.tables
WHERE table_schema = 'your_database'
AND data_free > 0;-- 重建表减少碎片
OPTIMIZE TABLE table_name;
-- 或者
ALTER TABLE table_name ENGINE=InnoDB;

4. 常见问题与解决方案

问题1:频繁的页分裂
-- 监控页分裂
SHOW GLOBAL STATUS LIKE 'innodb_page_splits';-- 解决方案:使用自增主键
ALTER TABLE problematic_table 
ADD COLUMN new_id BIGINT AUTO_INCREMENT PRIMARY KEY FIRST;
问题2:回表操作过多
-- 问题查询
SELECT * FROM users WHERE age = 25;  -- 需要回表-- 解决方案1:覆盖索引
CREATE INDEX idx_age_cover ON users(age, name, email);
SELECT name, email FROM users WHERE age = 25;  -- 无需回表-- 解决方案2:包含列索引(MySQL 8.0+)
CREATE INDEX idx_age_include ON users(age) INVISIBLE;  -- 隐形索引测试
问题3:索引选择性差
-- 检查索引选择性
SELECT COUNT(DISTINCT column_name) / COUNT(*) AS selectivity,COUNT(DISTINCT column_name) AS unique_values,COUNT(*) AS total_rows
FROM table_name;-- 选择性低于0.1的索引考虑删除或重新设计

总结

核心要点回顾

  1. 聚集索引:数据即索引,索引即数据,查询效率高但每表只能有一个
  2. 非聚集索引:索引与数据分离,灵活性高但可能需要回表操作
  3. 选择原则:根据查询模式和性能需求选择合适的索引策略
  4. 优化策略:合理设计复合索引,利用覆盖索引减少回表

设计建议

  • 主键设计:优先使用自增整型主键作为聚集索引
  • 查询优化:基于实际查询模式设计非聚集索引
  • 性能监控:定期分析索引使用情况,及时优化
  • 维护策略:建立索引生命周期管理机制

通过深入理解聚集索引和非聚集索引的原理与应用,可以更好地设计数据库结构,优化查询性能,为应用系统提供高效稳定的数据访问支撑。

http://www.xdnf.cn/news/17576.html

相关文章:

  • 蚁剑--安装、使用
  • 基于跨平台的svg组件编写一个svg编辑器
  • 《Fast Automatic White Balancing Method by Color Histogram Stretching》论文笔记
  • ChatGpt 5系列文章1——编码与智能体
  • 自建知识库,向量数据库 体系建设(一)之BERT 与.NET 4.5.2 的兼容困境:技术代差下的支持壁垒
  • 2025杭电多校第七场 矩形框选、伤害冷却比 个人题解
  • Ansible 详细笔记
  • 高性能web服务器Nginx
  • Linux 系统运维、网络、SQL Server常用命令
  • Mac如何安装telnet命令
  • 3D文档控件Aspose.3D实用教程:在 C# 中将 3MF 文件转换为 STL
  • 深度学习与遥感入门(六)|轻量化 MobileNetV2 高光谱分类
  • UNet改进(32):结合CNN局部建模与Transformer全局感知
  • HTTP应用层协议-长连接
  • (25.08)Ubuntu20.04+ROS1复现LIO-SAM
  • 2025年最新原创多目标算法:多目标酶作用优化算法(MOEAO)求解MaF1-MaF15及工程应用---盘式制动器设计,提供完整MATLAB代码
  • 【代码随想录day 18】 力扣 501.二叉搜索树中的众数
  • 力扣热题100------279.完全平方数
  • 吉利汽车7月销量超23.7万辆 同比增长58%
  • 【嵌入式C语言】
  • 【10】微网优联——微网优联 嵌入式技术一面,校招,面试问答记录
  • 数据结构:串、数组与广义表
  • IP分片(IP Fragmentation)
  • 力扣109:有序链表转换二叉搜索树
  • docter的使用、vscode(cursor)和docker的连接,详细分析说明
  • 【3D Gen 入坑(1)】Hunyuan3D-Paint 2.1 安装 `custom_rasterizer` 报错完整排查
  • 面试题-----RabbitMQ
  • MySQL的索引(索引的数据结构-B+树索引):
  • 嵌入式Linnux学习 -- 软件编程2
  • 【已解决】报错:WARNING: pip is configured with locations that require TLS/SSL