MYSQL 总结

🔥 MySQL 小重点(精华中的精华)

一、WHERE 和 HAVING 的区别(必考!)

对比项 WHERE HAVING
执行时机 分组筛选 分组筛选
能否用聚合函数 ❌ 不能用 ✅ 能用
能否用别名 ❌ 不能用 ✅ 能用

sql

复制代码
-- ✅ 正确:WHERE 在分组前
SELECT city, COUNT(*) FROM users WHERE age > 18 GROUP BY city;

-- ✅ 正确:HAVING 在分组后,用聚合函数
SELECT city, COUNT(*) as cnt FROM users GROUP BY city HAVING cnt > 5;

-- ❌ 错误:WHERE 不能用聚合函数
SELECT city, COUNT(*) FROM users WHERE COUNT(*) > 5 GROUP BY city;

二、COUNT 的三种用法区别

sql

复制代码
COUNT(*)   -- 统计所有行,包括 NULL(最慢,最准确)
COUNT(1)   -- 和 COUNT(*) 一样,性能相同
COUNT(列名) -- 统计该列非 NULL 的行数

-- 实际区别
SELECT COUNT(*), COUNT(age), COUNT(phone) FROM users;
-- 如果 phone 列有很多 NULL,COUNT(phone) 会少很多

三、DELETE 和 TRUNCATE 的区别

对比项 DELETE TRUNCATE
速度 慢(逐行删) 快(直接清空)
能否回滚 ✅ 能 ❌ 不能
重置自增ID ❌ 不重置 ✅ 重置为1
触发触发器 ✅ 触发 ❌ 不触发

sql

复制代码
DELETE FROM users;      -- 可回滚,ID继续增长
TRUNCATE TABLE users;   -- 不可回滚,ID从1开始

四、CHAR 和 VARCHAR 的区别

对比项 CHAR VARCHAR
长度 固定长度 可变长度
存储空间 固定分配 实际长度+1
速度 更快 稍慢
适用场景 长度固定(如手机号、身份证) 长度不定(如姓名、地址)

sql

复制代码
-- CHAR(10) 存 "abc":占10个字节
-- VARCHAR(10) 存 "abc":占4个字节(3+1)

五、IN 和 EXISTS 的区别(面试常问)

sql

复制代码
-- IN:适合子查询结果小的情况
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);

-- EXISTS:适合主表小、子查询大的情况
SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

执行顺序不同

  • IN:先执行子查询,再执行主查询

  • EXISTS:先执行主查询,再执行子查询


六、UNION 和 UNION ALL 的区别

sql

复制代码
UNION      -- 合并结果并去重(慢)
UNION ALL  -- 合并结果不去重(快,推荐)

sql

复制代码
-- 两个查询结果合并
SELECT name FROM users_a
UNION ALL
SELECT name FROM users_b;

七、LIKE 模糊查询的坑

sql

复制代码
-- % 在右边:可以用索引(快)
WHERE name LIKE '张%'     -- ✅ 以张开头的

-- % 在左边:不能用索引(慢)
WHERE name LIKE '%三'     -- ❌ 以三结尾的

-- % 两边都有:不能用索引(很慢)
WHERE name LIKE '%三%'    -- ❌ 包含三的

八、NULL 的特殊处理(必坑指南)

sql

复制代码
-- NULL 参与运算结果都是 NULL
SELECT 1 + NULL;     -- 结果 NULL
SELECT 'a' || NULL;  -- 结果 NULL

-- 处理 NULL 的函数
SELECT IFNULL(age, 0) FROM users;      -- 如果 age 是 NULL 就返回 0
SELECT COALESCE(age, phone, 0) FROM users;  -- 返回第一个非 NULL 的值

九、EXPLAIN 查看执行计划(调优必备)

sql

复制代码
EXPLAIN SELECT * FROM users WHERE name = '张三';

看懂这几列就够了:

列名 含义
type 访问类型 refeq_ref ALL(全表扫描)
possible_keys 可能用的索引 有值 NULL
key 实际用的索引 有值 NULL
rows 扫描行数 越小越好 越大越慢
Extra 额外信息 Using index Using filesort

十、索引失效的情况(背下来!)

sql

复制代码
-- ❌ 这些情况索引会失效
WHERE name LIKE '%三'           -- 左模糊
WHERE age + 1 = 20              -- 对列做了运算
WHERE LEFT(phone, 3) = '138'    -- 用了函数
WHERE name = '张三' OR age = 18  -- OR 两边有一个没索引
WHERE age != 18                 -- 不等于
WHERE name IS NULL              -- IS NULL 可能失效(看版本)

-- ✅ 正确写法
WHERE name LIKE '张%'            -- 右模糊
WHERE age = 19                  -- 把运算放右边
WHERE phone LIKE '138%'         -- 用 LIKE

十一、自增 ID 的坑

sql

复制代码
-- 删除最后一条后,新插入的ID不会复用
DELETE FROM users WHERE id = 10;
INSERT INTO users ...;  -- 新ID是11,不是10

-- 想要重置自增ID
TRUNCATE TABLE users;   -- 方法1:清空表
ALTER TABLE users AUTO_INCREMENT = 1;  -- 方法2:手动重置

十二、常用字符串函数

sql

复制代码
CONCAT('a', 'b', 'c')      -- 拼接:'abc'
LENGTH('你好')              -- 字节长度:6
CHAR_LENGTH('你好')         -- 字符长度:2
SUBSTRING('abcdef', 2, 3)  -- 截取:'bcd'
REPLACE('abc', 'b', 'x')   -- 替换:'axc'
TRIM('  abc  ')            -- 去空格:'abc'
UPPER('abc')               -- 大写:'ABC'
LOWER('ABC')               -- 小写:'abc'

十三、常用日期函数

sql

复制代码
NOW()           -- 当前日期时间:2024-01-15 10:30:00
CURDATE()       -- 当前日期:2024-01-15
CURTIME()       -- 当前时间:10:30:00
YEAR(NOW())     -- 提取年:2024
MONTH(NOW())    -- 提取月:1
DAY(NOW())      -- 提取日:15
DATE_ADD(NOW(), INTERVAL 1 DAY)   -- 加1天
DATEDIFF('2024-01-20', '2024-01-15')  -- 日期差:5

十四、CASE WHEN 条件判断

sql

复制代码
-- 相当于 if-else
SELECT 
    name,
    score,
    CASE 
        WHEN score >= 90 THEN '优秀'
        WHEN score >= 60 THEN '及格'
        ELSE '不及格'
    END as 等级
FROM students;

十五、最常用的3个优化技巧

sql

复制代码
-- 1. 只查需要的列,不用 SELECT *
SELECT id, name FROM users;  -- ✅
SELECT * FROM users;          -- ❌

-- 2. 分页查询用 LIMIT
SELECT * FROM orders ORDER BY id LIMIT 100;  -- ✅

-- 3. 用 EXISTS 代替 IN(子查询数据量大时)
SELECT * FROM users u 
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);  -- ✅

📌 一句话记住这些小重点

WHERE 分组前,HAVING 分组后;COUNT(*) 最准,TRUNCATE 更快;CHAR 固定 VARCHAR 变,左模糊会让索引失效;NULL 用 IS 不用等,UNION ALL 比 UNION 快;EXPLAIN 看执行计划,CASE WHEN 做条件判断。

相关推荐
北顾笙9802 小时前
day12-数据结构力扣
数据结构·算法·leetcode
漫随流水2 小时前
c++编程:D进制的A+B(1022-PAT乙级)
数据结构·c++·算法
paeamecium3 小时前
【PAT】 - Course List for Student (25)
数据结构·c++·算法·pat考试
漫随流水3 小时前
c++编程:说反话(1009-PAT乙级)
数据结构·c++·算法
披着羊皮不是狼3 小时前
深度解构栈内存的物理逻辑与系统保护
数据结构··底层原理
计算机安禾3 小时前
【数据结构与算法】第23篇:树、森林与二叉树的转换
c语言·开发语言·数据结构·c++·线性代数·算法·矩阵
hnjzsyjyj3 小时前
洛谷 P2015:二叉苹果树 ← 有依赖的背包问题
数据结构·有依赖的背包
苏宸啊4 小时前
哈希表开放定址法增删改查简单实现
数据结构·c++
玉小格4 小时前
动态内存管理
数据结构