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

SQL详细语法教程(四)约束和多表查询

以下是对 MySQL 语法 按分类的 超详细拆解,从概念本质、语法细节、执行原理到复杂场景,逐层深挖,帮你彻底吃透这些核心知识点:


一、基础 - 约束体系(数据完整性的「规则引擎」)

1. 约束的本质:数据的「法律条文」

  • 约束是 MySQL 强制数据遵循的规则,直接干预表的增 / 删 / 改操作,确保数据满足业务逻辑(如订单表的「金额必须 > 0」)。
  • 核心价值:预防脏数据(无效 / 矛盾 / 冗余数据),让表结构「自解释业务规则」,避免依赖程序层校验。

2. 约束类型全解析(带极端场景 + 底层逻辑)

(1)主键约束(PRIMARY KEY)
  • 绝对唯一性:表中每行必须有唯一标识,且值非空 + 不重复(相当于「身份证号」)。
  • 物理存储优化:InnoDB 会自动基于主键建立 聚簇索引(数据按主键顺序存储),查询时直接定位数据页,速度极快。
  • 语法细节
    -- 单字段主键(最常用)
    CREATE TABLE Employees (EmployeeID INT AUTO_INCREMENT, PRIMARY KEY (EmployeeID)  -- 隐式 NOT NULL + 唯一
    );-- 复合主键(多字段联合唯一,如「订单 + 商品」关联表)
    CREATE TABLE OrderItems (OrderID INT, ProductID INT, PRIMARY KEY (OrderID, ProductID)  -- 两字段组合唯一
    );--  Alter 新增主键(注意:已有数据必须满足唯一性,否则报错)
    ALTER TABLE Users 
    ADD PRIMARY KEY (UserID); 
    
  • 极端场景
    • 若表已有数据含重复值,ALTER ADD PRIMARY KEY 会直接失败,需先清理重复数据。
    • 主键字段尽量用 INT/BIGINT(占空间小,索引效率高),避免用 UUID(字符串索引大,查询慢)。
(2)唯一性约束(UNIQUE)
  • 逻辑约束:保证字段 / 字段组合的值唯一,但允许 NULL(与主键的区别:主键不允许 NULL,一个表只能有 1 个主键,但可多个 UNIQUE)。
  • 索引实现:MySQL 会自动为 UNIQUE 字段建立 唯一索引(但不组织数据存储,仅用于校验)。
  • 语法细节
    -- 单字段唯一(如用户邮箱)
    CREATE TABLE Users (Email VARCHAR(50) UNIQUE  -- 隐式创建唯一索引
    );-- 命名约束(方便删除/修改,推荐!)
    CREATE TABLE Products (ProductCode VARCHAR(20),CONSTRAINT unique_product_code UNIQUE (ProductCode)  -- 显式命名约束
    );-- 复合唯一(如「地区 + 门店编号」唯一)
    CREATE TABLE Stores (Region VARCHAR(20),StoreNo VARCHAR(10),UNIQUE (Region, StoreNo)  -- 两字段组合唯一
    );
    
  • 与主键的区别
    • 主键是「物理 + 逻辑」约束(影响存储结构),UNIQUE 仅逻辑约束(数据存储无变化)。
    • 主键字段不允许 NULL,UNIQUE 允许(NULL 不算重复,如多个 NULL 可共存)。
(3)外键约束(FOREIGN KEY)
  • 跨表关联:建立表与表的「父子关系」,子表(外键表)的字段值必须在父表(主键表)中存在,或为 NULL(若外键允许)。
  • 底层原理
    • 父表删除 / 更新记录时,子表关联数据的行为由 外键动作(ON DELETE/UPDATE)决定。
    • InnoDB 会自动为外键字段建立 普通索引(加速关联查询)。
  • 语法细节(关联 Departments 父表)
    CREATE TABLE Employees (EmployeeID INT AUTO_INCREMENT,DepartmentID INT,PRIMARY KEY (EmployeeID),-- 外键关联,父表是 Departments,字段是 DepartmentIDFOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)  -- 可选:外键动作(控制父表数据变更时,子表的行为)ON DELETE CASCADE   -- 父表删除,子表关联数据自动删除ON UPDATE CASCADE   -- 父表更新,子表关联数据自动更新
    );
    
  • 外键动作(关键!)
    • RESTRICT(默认):父表数据有子表关联时,禁止删除 / 更新(报错阻止)。
    • CASCADE:父表删除 / 更新,子表关联数据自动级联删除 / 更新(适合「强关联」场景,如订单删除,订单项也删)。
    • SET NULL:父表删除 / 更新,子表外键字段设为 NULL(需外键字段允许 NULL,适合「弱关联」场景,如部门解散,员工部门字段置空)。
    • NO ACTION:同 RESTRICT(SQL 标准语法,效果一样)。
(4)检查约束(CHECK)
  • 逻辑校验:自定义条件校验字段值(如 Salary > 0Age BETWEEN 18 AND 60)。
  • MySQL 特殊点:MySQL 8.0 前,CHECK 只是「语法糖」,不实际校验;8.0 后真正生效(严格校验)。
  • 语法细节
    CREATE TABLE Employees (Salary DECIMAL(10,2),-- 8.0+ 严格校验:工资必须>0CHECK (Salary > 0)  
    );-- 复杂条件(如邮箱格式,实际建议程序层校验,这里仅演示)
    CREATE TABLE Users (Email VARCHAR(50),CHECK (Email LIKE '%@%.%')  -- 简单邮箱格式校验
    );
    
  • 历史坑点:MySQL 5.7 及以下,CHECK 写了也没用,需用触发器 / 程序层实现校验。
(5)默认约束(DEFAULT)
  • 插入兜底值:插入数据时,若字段未赋值,自动填充默认值(如 CREATE_TIME DEFAULT NOW())。
  • 语法细节
    CREATE TABLE Orders (OrderStatus VARCHAR(20) DEFAULT '待支付',  -- 未指定状态时,默认「待支付」CreateTime DATETIME DEFAULT CURRENT_TIMESTAMP  -- 自动填充当前时间
    );
    
  • 注意DEFAULT 仅在 INSERT 未显式赋值 时生效,若赋值为 NULL(且字段允许 NULL),则存 NULL,不触发 DEFAULT。

二、基础 - 多表查询(关联数据的「拼图魔法」)

1. 多表查询的本质:关系数据库的核心能力

  • 解决 「数据分散在多张表,但业务需要整合结果」 的问题(如「查订单时,同时获取用户信息 + 商品信息」)。
  • 核心逻辑:通过「连接条件」(JOIN ON)匹配表之间的关联字段,将多张表「拼接」成临时结果集。

2. 子查询分类(按返回结果形态)

(1)行子查询(返回 1 行数据)
  • 本质:子查询结果是「单行多列」,可用于 精准匹配(如对比某行的多字段值)。
  • 语法 + 场景
    -- 需求:查与「员工 123」工资、部门都相同的其他员工
    SELECT * FROM Employees 
    WHERE (Salary, DepartmentID) = (  -- 匹配两行的多字段SELECT Salary, DepartmentID FROM Employees WHERE EmployeeID = 123
    ) 
    AND EmployeeID != 123;  -- 排除自己
    
  • 执行原理:子查询先返回 1 行(Salary=10000, DepartmentID=5),主查询用 (Salary, DepartmentID) = (10000,5) 筛选。
(2)表子查询(返回 1 个临时表)
  • 本质:子查询结果是「多行多列」,可当作 临时表 参与主查询(常用于复杂过滤后,再关联其他表)。
  • 语法 + 场景
    -- 需求:查「工资前 10 员工」的详细信息(含部门名称)
    SELECT e.*, d.DepartmentName 
    FROM (-- 子查询:先筛选工资前 10 的员工(临时表)SELECT * FROM Employees ORDER BY Salary DESC LIMIT 10  
    ) AS e  -- 给临时表起别名 e
    JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID;  -- 再关联部门表
    
  • 执行顺序:先执行子查询生成临时表(10 行),再与 Departments 表 JOIN,效率比直接多表 JOIN 高(减少关联数据量)。
(3)标量子查询(返回 1 个值)
  • 本质:子查询结果是「单行单列」,可用于 比较 / 计算(如对比平均值、最大值)。
  • 语法 + 场景
    -- 需求:查工资高于「公司平均工资」的员工
    SELECT * FROM Employees 
    WHERE Salary > (SELECT AVG(Salary) FROM Employees  -- 子查询返回一个值(平均工资)
    );
    
  • 执行原理:子查询先计算出平均工资(如 8000),主查询筛选 Salary > 8000 的行。
(4)列子查询(返回 1 列多行)
  • 本质:子查询结果是「单列多行」,常用于 IN/ANY/ALL 等集合比较。
  • 语法 + 场景
    -- 需求:查「属于研发部或市场部」的员工(部门 ID 来自子查询)
    SELECT * FROM Employees 
    WHERE DepartmentID IN (SELECT DepartmentID FROM Departments WHERE DepartmentName IN ('研发部', '市场部')  -- 子查询返回多个 ID
    );
    
  • 替代语法(效率差异)
    • IN 适合子查询结果少的情况;若结果极多,用 JOIN 更高效(避免多次匹配)。
    • ANY/ALL 用法:
      -- 查工资比「研发部任意一人」高的员工(只要比其中一个高)
      SELECT * FROM Employees 
      WHERE Salary > ANY (SELECT Salary FROM Employees WHERE DepartmentID = (SELECT DepartmentID FROM Departments WHERE DepartmentName = '研发部')
      );
      

三、多表查询 - 连接类型(JOIN 核心逻辑)

1. 内连接(INNER JOIN)

  • 本质:只返回 两张表中匹配条件的记录(即连接条件成立的行),是最常用的连接方式。
  • 执行原理
    • 对表 A 和表 B,逐行匹配 A.column = B.column,仅保留匹配成功的行 → 临时结果集。
  • 语法 + 场景
    -- 基础用法(两表连接)
    SELECT e.EmployeeName, d.DepartmentName 
    FROM Employees e
    JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID;  -- 连接条件-- 多表内连接(三表及以上,如「订单 + 商品 + 用户」)
    SELECT o.OrderID, u.UserName, p.ProductName 
    FROM Orders o
    JOIN Users u ON o.UserID = u.UserID
    JOIN Products p ON o.ProductID = p.ProductID;
    
  • 特点
    • 结果集行数 = 匹配成功的行数,若某表无匹配,该行直接消失。
    • 性能:因只保留匹配行,数据量小,查询速度快(尤其适合关联条件明确的场景)。

2. 外连接(OUTER JOIN)

(1)左外连接(LEFT JOIN / LEFT OUTER JOIN)
  • 本质:返回 左表的全部记录,即使右表无匹配;右表无匹配的字段填 NULL
  • 执行原理
    • 先取左表所有行 → 逐行匹配右表 → 匹配成功则合并数据;失败则右表字段填 NULL
  • 语法 + 场景
    -- 需求:查所有员工,包括「未分配部门」的(部门字段可能为 NULL)
    SELECT e.EmployeeName, d.DepartmentName 
    FROM Employees e
    LEFT JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID;
    
  • 关键场景
    • 统计「左表全量 + 右表关联」(如「用户表 + 订单表」,查所有用户,包括未下单的)。
(2)右外连接(RIGHT JOIN / RIGHT OUTER JOIN)
  • 本质:与左外连接相反,返回 右表的全部记录,左表无匹配则填 NULL
  • 语法 + 场景
    -- 需求:查所有部门,包括「无员工」的部门(员工字段可能为 NULL)
    SELECT e.EmployeeName, d.DepartmentName 
    FROM Employees e
    RIGHT JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID;
    
  • 注意
    • 左 / 右外连接可通过 交换表顺序 互相转换(如 A LEFT JOIN B 等价于 B RIGHT JOIN A),实际用 LEFT JOIN 更多(逻辑更直观)。
(3)全外连接(FULL JOIN / FULL OUTER JOIN)
  • MySQL 支持问题:MySQL 原生不支持 FULL JOIN,需用 UNION + 左右外连接 模拟。
  • 模拟语法
    -- 需求:查所有员工 + 所有部门,包括双方无匹配的记录
    SELECT e.EmployeeName, d.DepartmentName 
    FROM Employees e
    LEFT JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID
    UNION  -- 合并左右外连接结果(去重)
    SELECT e.EmployeeName, d.DepartmentName 
    FROM Employees e
    RIGHT JOIN Departments d 
    ON e.DepartmentID = d.DepartmentID;
    
  • 执行原理
    • 先 LEFT JOIN 取左表全量 + 右表匹配;再 RIGHT JOIN 取右表全量 + 左表匹配 → UNION 去重(若用 UNION ALL 则保留重复)。

3. 自连接(SELF JOIN)

  • 本质:表与 自身连接(把一张表当两张表用),解决「表内层级关系」问题(如「员工表」的上级领导也在同一张表)。
  • 语法 + 场景
    -- 需求:查员工姓名 + 其直属领导姓名(领导也在 Employees 表)
    SELECT e.EmployeeName, m.EmployeeName AS ManagerName 
    FROM Employees e
    -- 自连接:e.ManagerID 关联 e.EmployeeID(自己关联自己)
    JOIN Employees m 
    ON e.ManagerID = m.EmployeeID;
    
  • 执行原理
    • 把 Employees 表拆成 e(员工)和 m(领导)两张虚拟表 → 匹配 e.ManagerID = m.EmployeeID
  • 典型场景
    • 层级结构(部门经理 → 员工)、评论回复(父评论 → 子评论)等。

4. 联合查询(UNION / UNION ALL)

  • 本质:合并 多个查询的结果集(要求字段数、字段类型兼容)。
  • 语法 + 差异
    -- UNION:合并后去重(效率低,需排序去重)
    SELECT Column1 FROM TableA
    UNION
    SELECT Column1 FROM TableB;-- UNION ALL:合并后保留所有行(效率高,直接拼接)
    SELECT Column1 FROM TableA
    UNION ALL
    SELECT Column1 FROM TableB;
    
  • 关键场景
    • 合并不同条件的结果(如「查所有普通用户 + 所有管理员用户」)。
    • 跨库查询(需开启 FEDERATED 引擎,实际少用,更多用程序层合并)。

四、多表查询 - 高级子查询(复杂场景的「手术刀」)

1. 标量子查询(复习 + 深化)

  • 极端场景
-- 需求:给每个员工的工资,加上公司平均工资的 10%(复杂计算场景)
UPDATE Employees 
SET Salary = Salary + (SELECT AVG(Salary) * 0.1 FROM Employees  -- 子查询先算出平均工资的 10%,作为标量值参与更新
)
WHERE DepartmentID = 5;  -- 仅更新部门 5 的员工
  • 执行细节
    • 子查询会先执行一次(计算出全公司平均工资的 10%,比如 800),然后主查询批量更新符合条件的员工(工资 + 800)。
    • 若子查询返回 NULL(比如表为空),则 Salary + NULL 结果为 NULL,需用 COALESCE 处理:
UPDATE Employees 
SET Salary = Salary + COALESCE((SELECT AVG(Salary) * 0.1 FROM Employees), 0  -- 若平均工资为 NULL(表空),则加 0
)
WHERE DepartmentID = 5;

2. 列子查询(复习 + 深化)

  • 复杂过滤场景
-- 需求:查「工资高于其所在部门平均工资」的员工(子查询返回部门平均工资列)
SELECT EmployeeName, Salary, DepartmentID 
FROM Employees e
WHERE Salary > (SELECT AVG(Salary) FROM Employees WHERE DepartmentID = e.DepartmentID  -- 关联外层表的 DepartmentID,实现「按部门分组」
);
  • 执行原理
    • 这是 相关子查询(子查询依赖主查询的 e.DepartmentID),主查询每遍历一行员工数据,子查询就执行一次(按部门算平均工资),性能可能较低(数据量大时)。
    • 优化方案:用 JOIN 改写(先算部门平均工资,再关联员工表):
WITH DeptAvg AS (SELECT DepartmentID, AVG(Salary) AS AvgSalaryFROM Employees GROUP BY DepartmentID
)
SELECT e.EmployeeName, e.Salary, e.DepartmentID 
FROM Employees e
JOIN DeptAvg d 
ON e.DepartmentID = d.DepartmentID 
AND e.Salary > d.AvgSalary;

3. 行子查询(复习 + 深化)

  • 跨表匹配场景
-- 需求:同步「员工表」和「员工备份表」的工资(当员工 ID、部门 ID 都匹配时更新)
UPDATE Employees e
SET e.Salary = (SELECT b.Salary FROM EmployeeBackup bWHERE (b.EmployeeID, b.DepartmentID) = (e.EmployeeID, e.DepartmentID)  -- 行匹配
)
WHERE EXISTS (SELECT 1 FROM EmployeeBackup bWHERE (b.EmployeeID, b.DepartmentID) = (e.EmployeeID, e.DepartmentID)
);
  • 执行细节
    • 子查询返回的是「行数据」(Salary),主查询通过行匹配条件 (b.EmployeeID, b.DepartmentID) = (e.EmployeeID, e.DepartmentID) 找到对应的备份工资。
    • WHERE EXISTS 用于避免更新时子查询返回 NULL 导致主表字段被置空(若不加,无匹配的员工工资会被设为 NULL)。

4. 表子查询(复习 + 深化)

  • 多层嵌套 + 分页场景
-- 需求:查「工资前 10 员工」的部门信息,且只取部门表的前 5 条结果(多层限制)
SELECT d.* 
FROM (SELECT DepartmentID FROM (SELECT DepartmentID FROM Employees ORDER BY Salary DESC LIMIT 10  -- 先取工资前 10 员工的部门 ID(表子查询 1)) AS TopDepts GROUP BY DepartmentID  -- 去重部门 ID(避免重复部门)
) AS UniqueDepts
JOIN Departments d 
ON UniqueDepts.DepartmentID = d.DepartmentID 
LIMIT 5;  -- 再取前 5 个部门信息(最终结果限制)
  • 执行顺序
    • 最内层表子查询:SELECT DepartmentID FROM Employees ORDER BY Salary DESC LIMIT 10 → 得到 10 个员工的部门 ID(可能重复)。
    • 中间层:GROUP BY DepartmentID → 去重,得到唯一部门 ID 列表。
    • 最外层:关联 Departments 表,再限制取前 5 条部门信息。
    • 这种多层嵌套在复杂报表场景常见,但要注意索引优化(如给 Employees.Salary 加索引)。

五、多表关系设计(业务与表结构的「粘合剂」)

1. 三种核心关系(从业务到表结构)

(1)一对多(1:N)
  • 业务场景:部门(1)→ 员工(N)、分类(1)→ 商品(N)。
  • 表结构设计
    • 在「多」的一方(员工表)添加外键,关联「一」的一方(部门表)的主键。
    CREATE TABLE Departments (DepartmentID INT PRIMARY KEY,DepartmentName VARCHAR(50)
    );CREATE TABLE Employees (EmployeeID INT PRIMARY KEY,DepartmentID INT,FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
    );
    
  • 数据插入顺序
    • 必须先插父表(Departments),再插子表(Employees)(否则外键约束报错)。
    • 删除父表记录时,需先删子表关联记录,或设置 ON DELETE CASCADE
(2)多对多(N:M)
  • 业务场景:学生(N)→ 课程(M)、订单(N)→ 商品(M)。
  • 表结构设计
    • 新增「中间表」,包含两个外键(分别关联双方主键),可加额外字段(如选课时间、购买数量)。
    CREATE TABLE Students (StudentID INT PRIMARY KEY
    );CREATE TABLE Courses (CourseID INT PRIMARY KEY
    );-- 中间表(学生-课程关联)
    CREATE TABLE StudentCourses (StudentID INT,CourseID INT,PRIMARY KEY (StudentID, CourseID),  -- 复合主键,避免重复关联FOREIGN KEY (StudentID) REFERENCES Students(StudentID),FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)
    );
    
  • 插入逻辑
    • 先插 Students、Courses 表,再插中间表(StudentCourses)。
    • 查询时,通过中间表 JOIN 实现多对多关联:
    SELECT s.StudentID, c.CourseID 
    FROM Students s
    JOIN StudentCourses sc ON s.StudentID = sc.StudentID
    JOIN Courses c ON sc.CourseID = c.CourseID;
    
(3)一对一(1:1)
  • 业务场景:用户(1)→ 用户详情(1)、订单(1)→ 发票(1)。
  • 表结构设计(两种方式)
    • 共享主键:详情表的主键同时是外键,关联主表主键(主表删,详情表删)。
    CREATE TABLE Users (UserID INT PRIMARY KEY
    );CREATE TABLE UserProfiles (UserID INT PRIMARY KEY,  -- 与 Users.UserID 相同FOREIGN KEY (UserID) REFERENCES Users(UserID)
    );
    
    • 外键 + 唯一约束:详情表用外键关联主表,且外键字段加唯一约束(保证 1:1)。
    CREATE TABLE UserProfiles (ProfileID INT PRIMARY KEY,UserID INT UNIQUE,  -- 唯一约束,确保一个用户只有一个详情FOREIGN KEY (UserID) REFERENCES Users(UserID)
    );
    
  • 使用场景
    • 拆分大表(如用户表字段太多,拆出不常用的详情表),或实现「可选扩展信息」(用户可填或不填详情)。

2. 关系设计的「坑点」与最佳实践

  • 外键的性能争议
    • 优点:强制数据完整性,减少脏数据。
    • 缺点:插入 / 删除时需校验外键,性能略低(高并发场景可考虑程序层控制,或用 ON DELETE CASCADE 减少操作)。
  • 中间表的索引优化
    • 多对多中间表的复合主键(如 (StudentID, CourseID))自动包含索引,查询时直接用该索引,无需额外创建。
  • 避免循环依赖
    • 表 A 外键关联表 B,表 B 外键关联表 A → 插入数据时死锁(需调整逻辑,用一方的外键允许 NULL 或延迟约束)。

六、执行计划与优化(让查询飞起来的「密码」)

1. 理解执行计划(EXPLAIN)

  • 语法
EXPLAIN SELECT * FROM Employees e
JOIN Departments d ON e.DepartmentID = d.DepartmentID;
  • 关键字段解读
    • id:查询中操作执行的顺序(复杂查询有多个 id,越小越先执行)。
    • select_type:查询类型(SIMPLE 简单查询、SUBQUERY 子查询、DERIVED 派生表等)。
    • table:涉及的表。
    • type:关联类型(性能从优到差:system > const > eq_ref > ref > range > index > ALL)。
      • eq_ref:主键 / 唯一索引匹配(最佳,如 JOIN 用主键关联)。
      • ref:普通索引匹配(较好,如外键关联)。
      • ALL:全表扫描(最差,需优化)。
    • rows:MySQL 认为会扫描的行数(越少越好)。
    • Extra:额外信息(如 Using index 表示用到覆盖索引,Using filesort 表示需额外排序,性能差)。

2. 常见优化场景

(1)多表 JOIN 优化
  • 问题type = ALL(全表扫描),rows 极大。
  • 优化
    • 给连接字段加索引(如 Employees.DepartmentID 和 Departments.DepartmentID 加索引)。
    • 小表驱动大表(JOIN 时,让结果集小的表在左边,减少循环次数)。
(2)子查询优化
  • 问题:相关子查询(子查询依赖主查询字段)导致多次执行,性能差。
  • 优化:用 JOIN 或 WITH 语法改写(如前面列子查询的优化方案)。
(3)索引覆盖(Covering Index)
  • 原理:查询所需字段都在索引中,无需回表查询数据行,速度极快。
  • 示例
-- 需求:查员工姓名和部门 ID(假设索引包含这两个字段)
SELECT EmployeeName, DepartmentID 
FROM Employees 
WHERE DepartmentID = 5;-- 优化:创建覆盖索引
CREATE INDEX idx_employee_department ON Employees (DepartmentID, EmployeeName);
  • 执行计划Extra 会显示 Using index,表示直接从索引取数据,无需访问数据页。

3. 避坑指南

  • 避免 SELECT *
    • 会导致回表查询所有字段,且无法利用覆盖索引。
  • 分页查询优化(LIMIT 大偏移量)
    • 问题:LIMIT 100000, 10 需扫描前 100010 行,性能差。
    • 优化:用主键定位,WHERE EmployeeID > 100000 LIMIT 10(需主键连续或有索引)。
  • 索引失效场景
    • 字段用函数(WHERE YEAR(CreateTime) = 2023)、类型隐式转换(WHERE DepartmentID = '5',实际是 INT 类型)→ 索引失效,全表扫描。

http://www.dtcms.com/a/336050.html

相关文章:

  • C语言相关简单数据结构:双向链表
  • Rust Async 异步编程(五):执行器和系统 I/O
  • Effective C++ 条款47: 使用traits classes表现类型信息
  • 基于强化学习的柔性机器人控制研究
  • 【大模型微调系列-07】Qwen3全参数微调实战
  • 关于虾的智能养殖系统的开发与实现(LW+源码+讲解+部署)
  • 【LeetCode题解】LeetCode 33. 搜索旋转排序数组
  • 详解flink java基础(一)
  • 嵌入式软件--->任务间通信
  • 【C++知识杂记1】智能指针及其分类
  • 05-实施任务控制
  • open Stack及VM虚拟机和其他平台虚拟机迁移至 VMware vSphere(esxi)虚拟化平台骨灰级后台磁盘替换法迁移方式
  • Maven依赖范围
  • C11期作业18(07.12)
  • 跨越南北的养老对话:为培养“银发中国”人才注入新动能
  • Linux——一些常用的其他命令
  • 学习Python中Selenium模块的基本用法(5:程序基本步骤)
  • MySQL数据库备份与恢复
  • 《棒球百科》奥运会取消了棒球·野球1号位
  • 旋钮键盘项目---foc讲解(闭环位置控制)
  • Redis-plus-plus API使用指南:通用操作与数据类型接口介绍
  • TensorFlow|张量流
  • C/C++复习(四)
  • 【LeetCode】单链表经典算法:移除元素,反转链表,约瑟夫环问题,找中间节点,分割链表
  • Javascript面试题及详细答案150道之(106-120)
  • 深度学习——常见的神经网络
  • Tomcat 类加载器原理深度解析
  • PowerPoint和WPS演示让多个对象通过动画同时出现
  • 近期(2021-2025)发行的常用国军标GJB 整理,2021,2022,2023,2024,2025
  • 深入理解QFlags:Qt中的位标志管理工具