mysql执行过程中对视图和存储过程的处理有各自独立的逻辑,同时都依托于mysql通用的SQL执行流程框架,了解这些处理逻辑能帮助开发者更好地使用这两类数据库对象。

mysql通用SQL执行流程概述
mysql接收到一条SQL语句后,通常会经过以下几个核心阶段:
- 客户端发送SQL到服务端,服务端先对SQL进行语法解析,生成抽象语法树
- 进行语义检查,验证表、字段等对象是否存在,权限是否合法
- 优化器对SQL进行优化,生成最优执行计划
- 执行器按照执行计划调用存储引擎接口读取或写入数据,返回结果
视图在mysql执行过程中的处理
视图本身是虚拟表,不存储实际数据,mysql对视图的处理分为定义存储和执行处理两部分。
视图定义的存储
创建视图时,mysql不会存储视图的查询结果,只会把视图的定义语句存储在系统表information_schema.VIEWS中,我们可以通过以下语句查看视图定义:
-- 查询test_db库下view_demo视图的定义 SELECT VIEW_DEFINITION FROM information_schema.VIEWS WHERE TABLE_SCHEMA = 'test_db' AND TABLE_NAME = 'view_demo';
视图的执行处理流程
当查询中引用视图时,mysql的处理逻辑如下:
- 解析阶段:识别到视图名称后,从系统表中读取视图的定义SQL
- 优化阶段:将视图的定义SQL和当前查询的SQL进行合并,生成合并后的完整查询语句,再对合并后的语句进行优化,生成执行计划。如果视图定义中包含聚合函数、DISTINCT、GROUP BY等无法合并的场景,mysql会将视图的定义SQL作为一个子查询来处理
- 执行阶段:按照优化后的执行计划执行合并后的SQL,获取结果返回
我们可以通过EXPLAIN语句查看引用视图的查询的执行计划,验证视图是否被合并:
-- 创建测试视图 CREATE VIEW view_user_info AS SELECT id, name, age FROM user_table WHERE status = 1; -- 查看引用视图的查询执行计划 EXPLAIN SELECT * FROM view_user_info WHERE age > 18;
存储过程在mysql执行过程中的处理
存储过程是提前编译好存储在服务端的一段程序,包含SQL语句和控制逻辑,其处理流程和普通SQL有明显区别。
存储过程的存储与预编译
创建存储过程时,mysql会对存储过程的语句进行语法解析和预编译,将编译后的二进制代码存储在系统表中,后续调用时不需要重复解析编译,这也是存储过程执行效率较高的原因之一。
存储过程的执行处理流程
调用存储过程时,mysql的处理逻辑如下:
- 解析阶段:识别到存储过程调用语句(如
CALL proc_name())后,从系统表中读取预编译后的存储过程代码 - 执行阶段:按照存储过程中的逻辑顺序执行,遇到SQL语句时,会走和普通SQL相同的解析、优化、执行流程,遇到控制逻辑(如IF、WHILE)时,由mysql的过程化执行引擎处理
- 结果返回:如果存储过程有输出参数或者返回结果集,会将结果返回给客户端
以下是一个简单的存储过程示例,以及调用时的处理逻辑说明:
-- 创建存储过程,根据输入的年龄查询用户信息
DELIMITER //
CREATE PROCEDURE proc_get_user_by_age(IN input_age INT)
BEGIN
-- 过程内的查询语句会走普通SQL的执行流程
SELECT id, name, age FROM user_table WHERE age > input_age;
END //
DELIMITER ;
-- 调用存储过程
CALL proc_get_user_by_age(18);
视图与存储过程处理的差异对比
两者的处理差异主要体现在以下几个维度:
| 对比维度 | 视图 | 存储过程 |
|---|---|---|
| 存储内容 | 仅存储定义SQL | 预编译后的二进制执行代码 |
| 执行触发方式 | 被查询引用时触发 | 通过CALL语句主动调用触发 |
| 处理逻辑 | 定义SQL与查询SQL合并后再优化执行 | 按过程逻辑顺序执行,内部SQL单独走执行流程 |
| 权限检查 | 检查视图权限和基表权限 | 检查存储过程调用权限,内部SQL检查对应对象权限 |
注意事项
- 视图如果定义复杂,合并后的SQL可能优化难度提升,建议尽量避免定义过于复杂的视图嵌套
- 存储过程中如果包含大量业务逻辑,会增加服务端的执行压力,不适合处理高并发的轻量查询
- 修改视图定义后,引用该视图的查询会重新合并新的定义SQL,而修改存储过程后需要重新编译,已有的调用会使用新的逻辑