markdown复制## 1. MySQL表操作基础与核心概念
作为关系型数据库的典型代表,MySQL的表操作构成了数据管理的基石。在实际项目中,合理的表结构设计和高效的数据查询往往直接影响着系统性能。我们先从最基础的建表操作说起:
创建表时除了字段定义,还需要特别注意引擎选择。以常用的InnoDB引擎为例,它支持事务和行级锁,适合大多数OLTP场景。建表语句中的关键参数包括:
```sql
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
注意:字符集推荐使用utf8mb4而非utf8,前者完整支持emoji等4字节字符,避免出现存储异常
字段类型选择直接影响存储效率和查询性能:
- 整型:根据数据范围选择TINYINT/SMALLINT/INT/BIGINT
- 字符串:定长用CHAR,变长用VARCHAR(超过255字符考虑TEXT)
- 时间:TIMESTAMP占用4字节,DATETIME占用8字节
2. 表结构优化实战技巧
2.1 索引设计黄金法则
索引是把双刃剑,合理使用能提升查询效率,滥用则会导致写入性能下降。复合索引的字段顺序遵循"最左前缀原则":
sql复制-- 有效使用索引的情况
SELECT * FROM orders WHERE user_id=100 AND status='paid'
-- 索引定义
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
常见索引失效场景:
- 对索引列使用函数:
WHERE DATE(create_time)='2023-01-01' - 隐式类型转换:
WHERE user_id='100'(user_id是整型) - 前导模糊查询:
WHERE name LIKE '%张'
2.2 分区表实战应用
当单表数据量超过千万级时,可以考虑分区策略。按时间范围分区是常见做法:
sql复制CREATE TABLE logs (
id INT AUTO_INCREMENT,
log_time DATETIME,
content TEXT,
PRIMARY KEY (id, log_time)
) PARTITION BY RANGE (TO_DAYS(log_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01'))
);
分区表使用注意事项:
- 查询条件必须包含分区键,否则会扫描所有分区
- 唯一索引必须包含分区字段
- 分区数量不宜过多(通常不超过1024个)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
3. 高效查询编写指南
3.1 EXPLAIN执行计划深度解析
理解EXPLAIN输出是优化查询的基础,关键指标解读:
| 列名 | 关键值 | 含义 |
|---|---|---|
| type | const/ref/range/index | 访问类型,性能从优到劣 |
| rows | 估算行数 | 需要检查的行数预估 |
| Extra | Using filesort | 需要额外排序,可能性能瓶颈 |
典型优化案例:
sql复制-- 优化前(全表扫描)
EXPLAIN SELECT * FROM products WHERE price > 100 ORDER BY create_time DESC;
-- 优化后(使用索引覆盖)
ALTER TABLE products ADD INDEX idx_price_time (price, create_time);
EXPLAIN SELECT id, price FROM products WHERE price > 100 ORDER BY create_time DESC;
3.2 联表查询性能陷阱
多表JOIN时容易出现性能问题,需要特别注意:
- 小表驱动原则:将数据量小的表作为驱动表
sql复制-- 推荐:user表数据量远小于orders
SELECT * FROM user u JOIN orders o ON u.id=o.user_id
- 避免笛卡尔积:确保ON条件有效
sql复制-- 错误示例:漏写关联条件导致全量组合
SELECT * FROM A, B WHERE A.status=1
- 子查询优化:能用JOIN尽量不用子查询
sql复制-- 不推荐
SELECT * FROM products WHERE category_id IN
(SELECT id FROM categories WHERE type='electronics')
-- 推荐
SELECT p.* FROM products p JOIN categories c
ON p.category_id=c.id WHERE c.type='electronics'
4. 高级查询技术与实战案例
4.1 窗口函数应用场景
MySQL 8.0+支持的窗口函数能简化复杂分析查询:
sql复制-- 计算每个部门的薪资排名
SELECT
name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
常用窗口函数:
- ROW_NUMBER(): 无重复序号
- RANK(): 并列排名会跳过序号
- DENSE_RANK(): 并列排名不跳过序号
- LAG/LEAD(): 访问前后行数据
4.2 公用表表达式(CTE)优化复杂查询
CTE能提升复杂查询的可读性和性能:
sql复制-- 找出销售额前10%的商品
WITH product_sales AS (
SELECT
product_id,
SUM(amount) AS total_sales,
PERCENT_RANK() OVER (ORDER BY SUM(amount) DESC) AS pct_rank
FROM order_items
GROUP BY product_id
)
SELECT * FROM product_sales WHERE pct_rank <= 0.1;
CTE的典型优势:
1.
