逻辑查询步骤
查询操作是关系数据库中使用最为频繁的操作,也是构成其他SQL语句(如DELETE、UPDATE)的基础。查询处理的顺序如下:
(7)SELECT (8) DISTINCT (1) FROM (3) JOIN (2) ON (4) WHERE (5) GROUP BY (6) HAVING (9) ORDER BY (10) LIMIT
1)FROM:对FROM子句中的左表 和右表 执行笛卡儿积(Cartesian product),产生虚拟表VT1。 2)ON:对虚拟表VT1应用ON筛选,只有那些符合 的行才被插入虚拟表VT2中。 3)JOIN:如果指定了OUTER JOIN(如LEFT OUTERJOIN、RIGHT OUTER JOIN),那么保留表中未匹配的行作为外部行添加到虚拟表VT2中,产生虚拟表VT3。如果FROM子句包含两个以上表,则对上一个连接生成的结果表VT3和下一个表重复执行步骤1)~步骤3),直到处理完所有的表为止。 4)WHERE:对虚拟表VT3应用WHERE过滤条件,只有符合 的记录才被插入虚拟表VT4中。 此时数据还没有分组,所以不能在where中出现对统计的过滤 5)GROUP BY:根据GROUP BY子句中的列,对VT4中的记录进行分组操作,产生VT5。 在GROUP BY阶段,数据库认为两个NULL值是相等的,因此会将NULL值分到同一个分组中。 6)CUBE|ROLLUP:对表VT5进行CUBE或ROLLUP操作,产生表VT6。 7)HAVING:对虚拟表VT6应用HAVING过滤器,只有符合 的记录才被插入虚拟表VT7中。* count(expr) 会返回expr不为NULL的行数,count(1)、count( )会返回包括NULL值在内的所有数量 8)SELECT:第二次执行SELECT操作,选择指定的列,插入到虚拟表VT8中。 9)DISTINCT:去除重复数据,产生虚拟表VT9。 10)ORDER BY:将虚拟表VT9中的记录按照 进行排序操作,产生虚拟表VT10。 如果不指定排序,数据并非总是按照主键顺序进行排序的。NULL被视为最小值 11)LIMIT:取出指定行的记录,产生虚拟表VT11,并返回给查询用户。 LIMIT n, m的效率是十分低的,一般可以通过在where条件中指定范围来优化 where id> ? limit 10**
物理查询
数据库也许并不会完全按照逻辑查询处理的方式来进行查询,MySQL数据库层有Parser和Optimizer两个组件。Parser的工作就是分析SQL语句,而Op-timizer的工作就是对这个SQL语句进行优化,选择一条最优的路径来选取数据,但是必须保证物理查询处理的最终结果和逻辑查询处理是相等的。
Explain语句简介
原文 http://shanks.leanote.com/post/MySQL查询过程