SQL DML 数据管理语言

type
status
date
slug
summary
tags
category
icon
password

一、DML 核心操作

操作
语法
说明
插入数据
INSERT INTO 表 (列1,列2) VALUES (值1,值2)
可单条或多条插入
删除数据
DELETE FROM 表 WHERE 条件
无 WHERE 会清空全表!
更新数据
UPDATE 表 SET 列=新值 WHERE 条件
支持同时改多列
示例

二、SELECT 查询详解

1. 查询类型
  1. 查询类型:
    1. 1、单表查询
      2、多表查询/连接查询
      内连接
      外连接
      左外连接
      右外连接
      3、嵌套查询/子查询
2. 基础查询
3. WHERE 条件筛选
类型
参数
示例
比较运算符
=, !=, >, >=, <, ≤
WHERE age > 80
逻辑运算符
and(并且), or(或者)
WHERE gender='M' AND age<70
BETWEEN
and(并且),or(或者)
WHERE age BETWEEN 70 AND 80
IN
in
WHERE name IN ('张三','李四')
模糊查询
通配符 % 任意长度任意字符 _ 任意单个字符
WHERE Tname LIKE "%ang%" WHERE Tname LIKE "H%" WHERE Tname LIKE "_H"
空值判断
IS NULL, IS NOT NULL
WHERE phone IS NULL
正则表达式
WHERE name RLIKE '^H’
正则
模式
描述
^
匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
$
匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
.
匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像 '[.\n]' 的模式。
[...]
字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^...]
负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
p1|p2|p3
匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
*
匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+
匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
{n}
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,m}
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。

正则表达式匹配的字符类

  • .:匹配任意单个字符。
  • ^:匹配字符串的开始。
  • $:匹配字符串的结束。
  • :匹配零个或多个前面的元素。
  • +:匹配一个或多个前面的元素。
  • ?:匹配零个或一个前面的元素。
  • [abc]:匹配字符集中的任意一个字符。
  • [^abc]:匹配除了字符集中的任意一个字符以外的字符。
  • [a-z]:匹配范围内的任意一个小写字母。
  • [0-9]:匹配一个数字字符。
  • \w:匹配一个字母数字字符(包括下划线)。
  • \s:匹配一个空白字符。
正则示例
4. 排序与限制
5. 聚合函数与分组
函数
作用
COUNT()
统计行数
AVG()
平均值
SUM()
求和
MAX()
最大值
MySQL 聚合函数用法 (1)
分组示例

三、高级查询技巧

1. 子查询(嵌套查询)
2. 多表连接(重点)
内连接特征:
连接类型
特点
语法
内连接
只返回匹配行
SELECT * FROM A INNER JOIN B ON A.id=B.id
左连接
左表全显示
SELECT * FROM A LEFT JOIN B ON A.id=B.id
右连接
右表全显示
SELECT * FROM A RIGHT JOIN B ON A.id=B.id
只有相关联字段存在相同值时,才会显示对应的结果
多表连接示例

四、索引优化指南

1. 索引的作用
  • 加速查询(避免全表扫描)
  • 适合频繁查询但少更新的列
2. 索引工作
  • 数据库默认查询数据的行为是全表扫描
  • 根据哪个字段创建索引,需要考虑前端用户的访问行为
  • 不建议在频繁更新的字段上创建索引
3. 索引操作
4. EXPLAIN 分析查询
关键输出
  • possible_keys: 表中存在的索引名称
  • typeALL(全表扫描)→ 需优化
  • key:使用的索引名称
  • rows:扫描行数
5. 索引失效场景
场景
参数
示例
说明
非等值查询
!= , >, <
WHERE age > 30
使用 !=<>>< 等时,可能导致索引失效。尤其是在低选择性(重复值多)的列上,优化器会觉得全表扫描比走索引更快。
模糊查询
LIKE, RLIKE
WHERE name LIKE '%张%'
LIKE通配符开头%xxx)无法用到索引。RLIKE / REGEXP 基本也不走索引。
隐式类型转换
WHERE id = '100'(id是整数)
字符串和数字比较时,MySQL 会做类型转换,导致索引失效。
OR 条件
OR
WHERE age=20 OR age=30
OR 两边的字段不是同一个索引时,可能会导致索引失效。
IN 子句
IN
WHERE id IN (1,2,3);
IN 里的值过多时,MySQL 可能会放弃索引,改用全表扫描。小集合(比如 IN(1,2,3,4))通常还是会用到索引。
函数或表达式操作列
WHERE YEAR(create_time) = 2024; -- 不走索引 WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01'; -- ✅ 走索引
如果对索引列做了计算、函数处理,索引无法使用。
联合索引未遵守“最左前缀原则”
WHERE a=1 AND b=2; -- 用索引 WHERE b=2; -- 不用索引
如果创建了联合索引 (a, b, c),查询必须先用到 a,否则索引失效。
索引失效对比表
查询场景
能走索引
不走索引
等值查询
WHERE age = 18
WHERE age != 18
范围查询
WHERE age BETWEEN 18 AND 30WHERE age > 18(左边是索引字段)
WHERE age < 18 并且索引不是最左字段时
模糊匹配 (LIKE)
LIKE 'abc%'(前缀匹配)
LIKE '%abc'LIKE '%abc%'(前缀是通配符 %
OR条件
WHERE age = 18 OR age = 20(如果两个字段都有索引,可能用索引合并)
WHERE age = 18 OR name LIKE '%a'(其中一个条件无法用索引,整体失效)
IN / NOT IN
WHERE id IN (1,2,3)
WHERE id NOT IN (1,2,3)(可能全表扫描)
函数或运算
WHERE YEAR(create_time) = 2024WHERE age + 1 = 20
隐式数据类型转换
WHERE age = 18(age 是 int,18 也是 int)
WHERE age = '18'(字符串转 int,会导致索引失效)
联合索引 (最左匹配原则)
索引 (a,b,c):✔ WHERE a=1WHERE a=1 AND b=2WHERE a=1 AND b=2 AND c=3
WHERE b=2WHERE c=3(跳过最左字段)✘ WHERE a>1 AND b=2(a 范围查询后,b,c 失效)
NULL 判断
WHERE age IS NULL(有时可走索引,取决于 MySQL 优化器)
WHERE age IS NOT NULL(一般全表扫描)
排序
ORDER BY age ASC(age 有索引)
ORDER BY func(age)(函数计算后无法使用索引)

👉 总结口诀:
  • 能走索引:等值、范围(左字段)、前缀匹配、最左匹配原则
  • 不走索引!=NOT IN、函数运算、数据类型转换、前缀是 % 的 LIKE

最佳实践:
  • WHEREJOIN 的列建索引
  • 避免在频繁更新的列建索引

补充:

  1. 索引失效补充
      • 明确 IN 和范围查询可能失效
  1. 连接查询优化
      • 强调多表连接时关联字段需建索引
  1. 安全提示
      • DELETE/UPDATEWHERE 会操作全表(危险!)
性能口诀:
  • 小表驱动大表(JOIN时)
  • 避免 SELECT *(只取必要列)
  • LIMIT 限制测试查询
 
Loading...