逻辑查询处理注意的地方

下面这些是从“技术内幕”书中归纳的。

“查询处理可将其分为逻辑查询处理与物理查询处理。前者表示执行查询应该产生怎样的结果,后者表示MYSQL数据库会根据优化器来选择某条路径去得到该结果。”

这里有一个完整的查询语句,且有它们的执行顺序:

(8)SELECT(9) DISTINCT<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<having_condition> 

(10)ORDER_BY<order_by_list>

(11)LIMIT<limit_number>

简单说明一下:SQL语言并不是完全按顺序执行的,第一个执行的是FROM子句,最后是LIMIT操作;在FROM子句中会对左表各右表(如果有)执行笛卡儿积,产生虚拟表VT1;接下来由ON条件进行筛选;另外SELECT选择列操作在每8个步骤执行。

简要说一下在一些步骤中注意的地方:

(1)过滤条件共有三个:ON,WHERE,HAVING

(2)对于OUTER JOIN中的过滤,在ON过滤器过滤完之后还会添加保留表中被ON条件过滤掉的记录,而WHERE 条件中被过滤掉的记录则是永久过滤;在INNER JOIN 中两者没有差别

有这样的SQL语句:SELECT * FROM TABLE1 AS t1 LEFT JOIN TABLE2 AS t2 ON t1.col1=t2.col2AND t1.col3="xx" ;

其中,因为是AND连接了两个过滤条件,所以会对保留表中被排除的记录进行再次的添加操作;如果是用WHERE连接则不会。而要是INNER JOIN 的话,那么就没区别了。

(3)在WHERE子句中由于数据还没进行分组(根据查询语句的顺序),因此现在还不能在WHERE过滤器中使用where_condition=MIN(col)这类对统计的过滤

(4)同样,由于没有进行列的选取操作,因此在WHERE中使用SELECT里的别名也是不被允许的。如:

SELECT userName as name FROM user WHERE name="haha";

[Err] 1054 - Unknown column "name' in 'where clause'

按照那个顺序来看的话,只有在DISTINCT,ORDER_BY中才可能出现SELECT里出现的别名。

(5)子查询不能用做分组的聚合函数,如HAVING COUNT(SELECT ......)<2是不合语法的。

(6)SELECT部分在每8步才执行,列的别名不能在SELECT中的其它别名表达式中使用。如:

SELECT order_id as o,o+1 as n FORM orders;这也是不合语法的。

(7)对于使用了GROUP BY 的查询,再使用DISTINCT是多余的,因为已进行了分组

(8)在MYSQL数据库中,NULL值在升序过程中总是首先被选出,即NULL值在ORDER BY 子句中被视为最小值。

(9)对于大数据的应用来说,LIMIT(m,n)的效率十分低下,应该在应用层建立一定的缓存机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值