SQL查询原理及执行顺序

来源:互联网 发布:淘宝qb充值到一半 编辑:程序博客网 时间:2024/04/28 06:38

一、sql语句的执行步骤: 

1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。 
2) 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。 
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。 
4)表达式转换, 将复杂的 SQL 表达式转换为较简单的等效连接表达式。 
5)选择优化器,不同的优化器一般产生不同的“执行计划” 
6)选择连接方式, ORACLE 有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。 
7)选择连接顺序, 对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。 
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。 
9)运行“执行计划” 

二、oracle 共享原理: 

ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享 当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的 执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用 

三、oracle 语句提高查询效率的方法

1: where column in(select*from ... where ...); 2:... where exists (select'X'from ...where ...); 第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询 使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间 Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中 避免使用having字句 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销 

四、SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据; 
2、where子句基于指定的条件对记录行进行筛选; 
3、group by子句将数据划分为多个分组; 
4、使用聚集函数进行计算; 
5、使用having子句筛选分组; 
6、计算所有的表达式; 
7、使用order by对结果集进行排序 
逻辑查询处理步骤 
代码如下: 
Java代码  收藏代码
  1. (8)SELECT (9)DISTINCT   
  2. (11)<TOP_specification> <select_list>   
  3. (1)FROM <left_table>   
  4. (3)<join_type> JOIN <right_table>   
  5. (2)    ON <join_condition>   
  6. (4)WHERE <where_condition>   
  7. (5)GROUP BY <group_by_list>   
  8. (6)WITH {CUBE ROLLUP}   
  9. (7)HAVING <having_condition>   
  10. (10)ORDER BY <order_by_list>   
每个步骤产生一个虚拟表,该虚拟表被用作下一个步骤的输入。只有最后一步生成的表返回给调用者。如 
果没有某一子句,则跳过相应的步骤。 
1. FROM:对FROM子句中的前两个表执行笛卡尔积,生成虚拟表VT1。 
2. ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。 
3. OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行将作为外部行添加到VT2,生成VT3。 
如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到 
处理完所有的表为止。 
4. 对VT3应用WHERE筛选器。只有使<where_condition>为TRUE的行才被插入VT4。 
5. GROUP BY:按GROUP BY 子句中的列列表对VT4中的行分组,生成VT5。 
6. CUBEROLLUP:把超组插入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,并返回给调用者。 

以下是其它网友的补充: 
好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 "拼凑", 那您是不是得好好反省一下呢?, 呵呵). 
这样做确实是爽了自己, 可苦了机器, 服务器还需要在我们的杂乱无章的 SQL 语句中寻找它下一句需要执行的关键字在哪里. 
效率嘛, 由于我们的感觉神经对秒以下的变化实在不敏感, 暂且就认为自已写的 SQL 顺序无关紧要, "反正没什么变化!", 呵呵.其实服务器对每句 SQL 解析时间都会有详细记录的, 大家可以看一下自已按习惯写的 SQL 和按标准顺序写的SQL解析时间差别有多大. 
因此, 建议大家在平时工作中 SQL 语句按标准顺序写, 一是专业, 二是实用, 呵呵, 不过我觉得最主要的是心里感觉舒服. 
标准的 SQL 的解析顺序为: 
(1).FROM 子句, 组装来自不同数据源的数据 
(2).WHERE 子句, 基于指定的条件对记录进行筛选 
(3).GROUP BY 子句, 将数据划分为多个分组 
(4).使用聚合函数进行计算 
(5).使用 HAVING 子句筛选分组 
(6).计算所有的表达式 
(7).使用 ORDER BY 对结果集进行排序 
举例说明: 在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名"内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的. 
标准顺序的 SQL 语句为: 
select 考生姓名, max(总成绩) as max总成绩 
from tb_Grade 
where 考生姓名 is not null 
group by 考生姓名 
having max(总成绩) > 600 
order by max总成绩 
在上面的示例中 SQL 语句的执行顺序如下: 
(1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据 
(2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据 
(3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组 
(4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值 
(5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的. 
(7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序. 
好了,看了这些之后,我相信大家都知道了SQL中select语句的执行顺序了吧! 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 诛仙摆摊金币被扣怎么办 诛仙手游宠物亲密度满了怎么办 诛仙包裹满了怎么办 感觉自己心理有问题 怎么办 刺激战场手机配置低怎么办 国土防线2没反应怎么办 镜之边缘迷路了怎么办? 陌陌直播不清晰怎么办 夏利n5 1.0费油怎么办 gg修改器是病毒怎么办 传送门骑士联机读条慢怎么办 被打成轻伤派出所不抓人怎么办 有人上门找事怎么办算正当防卫吗 win10 电脑账户被停用怎么办 电脑一键还原后黑屏怎么办 win一键还原后黑屏怎么办 打架对方群殴我我怎么办 杀了人没钱赔怎么办 团伙打架被对方所刀捅伤怎么办 过失致人重伤赔偿不起怎么办 被别人打了派出所不管怎么办 先动手的被打伤怎么办 自为伤了人怎么办? 孩子被打不敢还手怎么办 小孩给电打了怎么办 电打了手都黑了怎么办 手指被电打伤了怎么办 电打了手有点麻怎么办 没打人对方确弄个轻伤证明怎么办 对人造成轻伤害怎么办 如果有人要砍我怎么办 美版手机坏了怎么办 战地4ping太高怎么办 喝了红牛睡不着怎么办 球球大作战总是闪退怎么办解决方法 球球大作战手机号己绑定怎么办 弄的底窝中药味太大怎么办 锤子手机上不了网怎么办 ppt没保存就卡了怎么办 ppt卡了没保存怎么办 匡威鞋舌头跑偏怎么办