QQ技术交流群:127591054海量资料免费学习,各个方向大神带你飞,欢迎爱学习的你哦。
作者企鹅:595696297欢迎交流数据。
当然总结的同时发现一篇超级详细的文章,大家有兴趣可以去读一下。
http://blog.csdn.net/freeking101/article/details/76522504
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
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
下面的视图也会产生错误
create view my_view
as
select *
from orders
order by orderid
在SQL中,表表达式中不允许使用带有ORDER BY子句的查询,而在T—SQL中却有一个例外(应用TOP选项)。
所以要记住,不要为表中的行假设任何特定的顺序。换句话说,除非你确定要有序行,否则不要指定ORDER BY 子句。排序是需要成本的,SQL Server需要执行有序索引扫描或使用排序运行符。
10、数据提取过程
当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作。
END~~