本文部分内容来自网络,
第一步:程序把语句发给数据库服务器执行。当我们在数据层执行select语句时,程序会把SQL语句发送给服务器端,让服务器端进程来处理这语句。
第二步:语句解析。
当程序把SQL语句传送到服务器后,服务器进程会对该语句进行解析。语句解析是一个复杂的过程,主要流程如下:
(1)查询高速缓存。服务器进程在接到程序传送过来的SQL语句时,不会直接去数据库查询,而是会先在数据库的高速缓存中去查找,是否存在相同语句的执行计划。如果存在,则服务器进程就会直接执行这个SQL语句,省去后续的工作。所以,采用高速数据缓存的话,可以提高SQL语句的查询效率。一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高,另一方面,也省去了语句解析等工作。
(2)语法检查。当在高速缓存中找不到对应的SQL语句时,则数据库服务器进程就会开始检查这条语句的语法合法性。如果服务器进程认为这条SQL语句不符合语法规则的时候,就会把这个错误信息,反馈给程序。
(3)语义检查。若SQL语句符合语法上的定义的话,则服务器进程接下去会对语句中的字段、表等内容进行检查。看看这些字段、表是否在数据库中。如果表名与列名不准确的话,则数据库会就会反馈错误信息给程序。
(4)获得对象解析锁。当语法、语义都正确后,系统就会对我们需要查询的对象加锁。这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象的结构发生改变。
(5)数据访问权限的核对。当语法、语义通过检查之后,服务器进程还会检查连接的用户是否有数据访问的权限。若用户不具有数据访问权限,则程序就不能够取得这些数据。
(6)确定最佳执行计划。当语句与语法都没有问题,权限也匹配的话,服务器进程开始根据一定的规则,对这条语句进行优化。当服务器进程的优化器确定这条查询语句的最佳执行计划后,就会将这条SQL语句与执行计划保存到数据高速缓存。
第三步:语句执行。
SQL语句执行也分两种情况。若被选择行所在的数据块已经被读取到数据缓冲区的话,则服务器进程会直接把这个数据传递给程序。若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲区中(ORACLE会将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享,当你执行一个SQL语句时,如果它和之前的执行过的语句完全相同,ORACLE就能很快获得已经被解析的语句以及最好的执行路径。)。
第四步:提取数据。
当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到程序的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询操作。
SQL 语言是为数据库声明了你想要什么样的数据,但没有说明怎么获取这些数据,你也不能显示的控制获取数据的每一个操作。一般的RDBMS会根据基于算法(如:ORACLE Rule-Based Optimization,简称为RBO)和现有的统计信息计算最佳的数据获取路径(如:ORACLE Cost-Based Optimization,简称为CBO)来分析如何获取数据。
SQL 执行并不一定按照语法顺序
大体上条SQL由下面的结构构成
- SELECT[DISTINCT]
- FROM
- WHERE
- GROUP BY
- HAVING
- UNION
- ORDER BY
数据库先执行的并不是SELECT, FROM 才是 SQL 语句执行的第一步。数据库在执行 SQL 语句的第一步是将数据从硬盘(缓冲区,或直接读取内存)加载到数据缓冲区中,以便对这些数据进行操作。SELECT 是在大部分语句执行了之后才执行的,例如你在写oracle GROUP BY 时 不能用 SELECT 中表的别名,只能用 table.a的形式,当然你也可以嵌套一层SELECT 使用别名,尔MYSQL就不会有这个顾虑。
WHERE:过滤表中数据的条件
GROUP BY:如何将上面过滤出的数据分组
HAVING:对上面已经分组的数据进行过滤的条件
SELECT:查看结果集中的哪个列,或列的计算结果
ORDER BY :按照什么样的顺序来查看返回的数据
FROM后面的表关联,是自右向左解析的
而WHERE条件的解析顺序是自下而上的。
也就是说,在写SQL文的时候,尽量把数据量大的表放在最右边来进行关联,
而把筛选力度大的条件放在WHERE语句的最下面。
UNION 总是排在在 ORDER BY 之前。很多人认为每个 UNION 段都能使用 ORDER BY 排序,但是根据 SQL 语言标准和各个数据库 SQL 的执行差异来看,这并不是真的。尽管某些数据库允许 SQL 语句对子查询(subqueries)或者派生表(derived tables)进行排序,但是这并不说明这个排序在 UNION 操作过后仍保持排序后的顺序.
最近公司要写wiki 顺便这里了最近学习的内容 发到这里 以飨读者.