我有以下查询:
SELECT c.* FROM companies AS c JOIN users AS u USING(companyid) JOIN jobs AS j USING(userid) JOIN useraccounts AS us USING(userid) WHERE j.jobid = 123;
我有以下问题:
USING语法是否与ON语法同义?
这些连接是从左到右评估的吗?换句话说,这个查询是否说:x =公司加入用户; y = x JOIN工作; z = y JOIN useraccounts;
如果问题2的答案是肯定的,那么假设公司表有companyid,userid和jobid列是否安全?
我不明白WHERE子句在引用别名"j"时如何用于在公司表上选择行
任何帮助,将不胜感激!
USING(fieldname)是在table1.fieldname = table2.fieldname上说的简写方式.
SQL没有定义JOIN完成的"顺序",因为它不是语言的本质.显然,必须在语句中指定一个订单,但INNER JOIN可以被认为是可交换的:您可以按任何顺序列出它们,您将得到相同的结果.
也就是说,当构造一个SELECT ... JOIN,特别是包含LEFT JOIN的那个时,我发现将第三个JOIN视为将第一个JOIN的结果连接到第一个JOIN,第四个JOIN作为连接的结果是有意义的.第二个JOIN的结果,依此类推.
更少见的是,指定的顺序会影响查询优化器的行为,因为它会影响启发式.
不是.查询组合的方式,它要求公司和用户都有一个companyid,job有一个userid和一个jobid,useraccounts有一个userid.但是,只有一个公司或用户需要一个用户ID才能使用JOIN.
WHERE子句使用jobs表提供的列过滤整个结果 - 即所有JOINed列.
我无法回答有关USING语法的问题.那真是怪了.我以前从未见过它,总是使用ON子句代替.
但我可以告诉你的是,JOIN操作的顺序是由查询优化器根据优化启发式系统构建其查询计划时动态确定的,其中一些是:
JOIN是否在主键字段上执行?如果是这样,则在查询计划中获得高优先级.
JOIN是否在外键字段上执行?这也是高优先级.
连接字段上是否存在索引?如果是这样,请优先考虑.
是否在WHERE子句中的字段上执行了JOIN操作?可以通过检查索引(而不是通过执行表扫描)来评估WHERE子句表达式吗?这是一个重要的优化机会,因此它成为一个重要的优先事项.
连接列的基数是多少?具有高基数的列为优化程序提供了更多机会来区分错误匹配(不满足WHERE子句或ON子句的那些),因此通常在低基数连接之前处理高基数连接.
连接表中有多少实际行?与仅包含100个值的表连接相比,创建的数据爆炸数要少于连接1000万行的表.
无论如何......关键是......有很多变量进入查询执行计划.如果您想了解MySQL如何优化其查询,请使用EXPLAIN语法.
这是一篇很好的文章:
http://www.informit.com/articles/article.aspx?p=377652
编辑:
回答你的第四个问题:你不是在查询"公司"表.您正在查询FROM和USING子句中所有四个表的联接交叉产品.
"j.jobid"别名只是该连接表集合中其中一列的完全限定名称.