欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL查询语句执行的流程,看完你就懂了

程序员文章站 2022-03-02 22:39:02
sql对于大多数来说大同小异,来简练的说一下一条sql查询语句执行的流程。 1、首先点击运行按钮,写好的sql语句会通过你用的客户端传到服务器。 2、服务器对sql语句进行解析,首先传过来的sql语...

sql对于大多数来说大同小异,来简练的说一下一条sql查询语句执行的流程。

1、首先点击运行按钮,写好的sql语句会通过你用的客户端传到服务器。

2、服务器对sql语句进行解析,首先传过来的sql语句会先从高数缓存中查找是否有相同的执行计划,如果找到就会直接执行,省去后面步骤节约时间。另外这个缓存是服务器的,内存的读取速度要比硬盘快的多!

3、服务器开始检查语句的合法性。检查传过来的sql语句是否符合语法规则,如果出现错误就会反馈给客户端。在这一步不会对sql语句本身的表,字段进行检查。这些是下一步需要检查的。

4、语言含义检查。当语法没有问题的时候,数据库开始检查表,字段是不是在数据字典中呀,如果不存在,同样会把错误信息反馈给客户端。所以在写查询语句的时候先是语法错误,语法没错了才是字段表结构错误。

5、获取对象锁。如上都正确了,数据库会把要查询的表对象进行加锁,以免在操作的同时,别人在对同一条数据或者表结构进行处理变更,从而保持一致。

6、数据访问权限核对。数据库会查询当前用户是否具有这张表的查询权限,当然数据权限这里需要如上都检查没问题再会到这一步!所以sql写正确未必能查到数据,sql写错误不知后面还有个坑。

7、最佳执行计划。数据库会对没有问题的sql,按照一定的规则进行优化,当然优化是有限的。具体的还需要自己在sql的同时考虑到sql语句的调优,已达到最快的效率!然后数据库会把这条sql语句以及执行计划放到数据库的高速缓存,以便下次再有相同语句,直接执行不用在检查了。

8、语句执行。

一是:若被选择行所在的数据块已经被读取到数据缓冲区的话,则服务器进程会直接把这个数据传递给客户端,而不是从数据库文件中去查询数据。

二是:若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲区中(buffer cache)

9、sql语句中的函数、关键字、排序等执行顺序。

mysql

SQL查询语句执行的流程,看完你就懂了

oracle

(8)select (9)distinct (11)<top num> <select list>
(1)from [left_table]
(3)<join_type> join <right_table>
(2)on <join_condition>
(4)where <where_condition>
(5)group by <group_by_list>
(6)with <cube | rollup>
(7)having <分组后筛选>
(10)order by <排序字段>

逻辑查询处理阶段简介
----------

1、from:对from子句中的前两个表执行笛卡尔积(cartesian product)(交叉联接),生成虚拟表vt1
2、on:对vt1应用on筛选器。只有那些使<join_condition>为真的行才被插入vt2。
3、outer(join):如 果指定了outer join(相对于cross join 或(inner join),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 vt2,生成vt3.如果from子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
4、where:对vt3应用where筛选器。只有使<where_condition>为true的行才被插入vt4.
5、group by:按group by子句中的列列表对vt4中的行分组,生成vt5.
6、cube|rollup:把超组(suppergroups)插入vt5,生成vt6.
7、having:对vt6应用having筛选器。只有使<having_condition>为true的组才会被插入vt7.
8、select:处理select列表,产生vt8.
9、distinct:将重复的行从vt8中移除,产生vt9.
10、order by:将vt9中的行按order by 子句中的列列表排序,生成游标(vc10).
11、top:从vc10的开始处选择指定数量或比例的行,生成表vt11,并返回调用者。

注:步骤10,按order by子句中的列列表排序上步返回的行,返回游标vc10.这一步是第一步也是唯一 一步可以使用select列表中的列别名的步骤。这一步不同于其它步骤的 是,它不返回有效的表,而是返回一个游标。sql是基于集合理论的。集合不会预先对它的行排序,它只是成员的逻辑集合,成员的顺序无关紧要。对表进行排序 的查询可以返回一个对象,包含按特定物理顺序组织的行。ansi把这种对象称为游标。理解这一步是正确理解sql的基础。

因为这一步不返回表(而是返回游标),使用了order by子句的查询不能用作表表达式。表表达式包括:视图、内联表值函数、子查询、派生表和共用表达式。它的结果必须返回给期望得到物理记录的客户端应用程序。例如,下面的派生表查询无效,并产生一个错误:

select * 
from(select orderid,customerid from orders order by orderid) 
as d