SQL 基础案例解析
1. 基础查询
1.1 分页查询
SELECT id, name, create_time
FROM user
WHERE status = 1
ORDER BY create_time DESC
LIMIT 10 OFFSET 20;
描述:查询状态为1的用户,按创建时间降序排列,获取第3页数据(每页10条)
原理:
WHERE
子句先过滤出 status=1 的记录ORDER BY
对结果按 create_time 降序排序LIMIT
和OFFSET
配合实现分页:LIMIT 10
表示每页10条OFFSET 20
表示跳过前20条(即第3页)
性能提示:
大表分页时,使用
WHERE id > last_id
比OFFSET
更高效确保 create_time 字段有索引
2. 多表关联
2.1 内连接
SELECT o.order_no, u.name, o.amount
FROM orders o
JOIN user u ON o.user_id = u.id
WHERE o.status = 2;
描述:查询状态为2的订单及其对应的用户信息
原理:
JOIN
执行内连接操作,只返回两表中匹配的行连接条件
o.user_id = u.id
建立关联执行顺序:
先执行
FROM
和JOIN
确定数据源然后
WHERE
过滤最后
SELECT
选择字段
优化建议:
确保 user_id 和 id 字段有索引
大表连接考虑使用覆盖索引
3. 聚合统计
3.1 分组统计
SELECT product_id,product_name,SUM(quantity) AS total_quantity,AVG(price) AS avg_price
FROM order_items
GROUP BY product_id, product_name;
描述:按商品统计销售总量和平均价格
原理:
GROUP BY
将数据按 product_id 和 product_name 分组对每个分组计算:
SUM(quantity)
求总数量AVG(price)
求平均价格
HAVING
可对分组结果再过滤(本例未使用)
执行流程:
读取 order_items 表数据
按分组字段创建临时分组
对每个分组计算聚合函数
返回结果集
4. 数据操作
4.1 条件更新
UPDATE products
SET stock = stock - 10,update_time = NOW()
WHERE id = 1001 AND stock >= 10;
描述:安全扣减库存(防止超卖)
原理:
WHERE
子句确保:只更新 id=1001 的商品
库存足够时才执行
SET
子句:原子性减少库存
同时更新修改时间
事务特性:
这条SQL本身是原子的
在高并发场景下应配合事务使用
5. 高级查询
5.1 窗口函数
SELECT user_id,order_date,amount,SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) AS running_total
FROM orders;
描述:计算每个用户的订单金额累计和
原理:
PARTITION BY
按用户分组ORDER BY
在每个分组内按日期排序SUM() OVER
计算从分组开始到当前行的累计和
执行过程:
先按 user_id 分区
在每个分区内按 order_date 排序
对每个分区逐行计算累计和
6. 索引使用建议
6.1 索引失效案例
SELECT * FROM users
WHERE DATE_FORMAT(create_time,'%Y-%m') = '2023-01';
问题:对 create_time 使用函数导致索引失效
优化方案:
SELECT * FROM users
WHERE create_time BETWEEN '2023-01-01' AND '2023-01-31';
原理:
原始查询对列使用函数,数据库无法使用索引
优化后使用范围查询,可以走索引
7. 执行计划分析
7.1 查看执行计划
EXPLAIN
SELECT o.*, u.name
FROM orders o JOIN users u ON o.user_id = u.id
WHERE o.amount > 1000;
关键指标:
type
:访问类型(const > eq_ref > ref > range > index > ALL)key
:实际使用的索引rows
:预估扫描行数Extra
:额外信息(Using index, Using temporary 等)
优化方向:
确保连接字段有索引
避免出现
Using temporary
和Using filesort