# 多表Join的时候，难道就只能这样写吗？

• ### 问题

• SELECT C.LINE_NAME,C.LINE_ID, D.PROD_SUB_FAMILY,D.PROD,D.PROD_DESC,E.OPER_DESC AS KEY_PROCESS,E.OPER_DESC_CN AS KEY_PROCESS_CN,Min(A.STEP) as STEP, SUM(QTY) AS WIP
FROM W_INVENTORY A  WITH (NOLOCK)
JOIN S_PRODUCT_LINE C WITH (NOLOCK)
ON A.FACILITY = C.FACILITY AND A.SITE=C.SITE AND A.LINE_ID=C.LINE_ID
JOIN S_PRODUCT D WITH (NOLOCK)
ON A.FACILITY = D.FACILITY AND A.SITE=D.SITE AND A.PROD=D.PROD
JOIN S_LOOKUP B WITH (NOLOCK)
ON A.FACILITY = B.FACILITY AND A.SITE=B.SITE AND B.ALPHA1=D.PROD_SUB_FAMILY AND B.TABLE_NAME='S_PROD_SUB_FAMILY' AND B.ALPHA2='Y'
JOIN S_OPERATION E WITH (NOLOCK) ON A.FACILITY = E.FACILITY AND A.SITE=E.SITE AND A.OPERATION=E.OPERATION AND E.DISPLAY_WIP_ON_DASHBOARD='Y'
WHERE A.FACILITY='NEO' AND A.SITE='SZ'
GROUP BY C.LINE_NAME,C.LINE_ID, D.PROD_SUB_FAMILY,D.PROD,D.PROD_DESC,E.OPER_DESC,E.OPER_DESC_CN              HAVING SUM(QTY) > 0

写法上是否可以优化呢？

If you haven't all the things you want,be grateful for the things you don't have that you didn't want.
2011年9月5日 7:30

### 答案

• 对于多表联结，sql server确实可能无法制定最优的查询计划。如果你可以确定哪些条件过滤性最强，而且对于大部分的参数条件来说都是这样，你可以通过query hint来指定sql采用什么样的执行计划。

比如联结顺序，联结方式(hash, merge, nested loop)等。但应谨慎使用query hint。

想不想时已是想，不如不想都不想。
2011年9月6日 4:23

### 全部回复

• 其中 B.TABLE_NAME='S_PROD_SUB_FAMILY' AND B.ALPHA2='Y'
这个过滤性最强，满足这个条件的就只有九笔。

于是我修改成：

SELECT C.LINE_NAME,C.LINE_ID, D.PROD_SUB_FAMILY,D.PROD,D.PROD_DESC,E.OPER_DESC AS KEY_PROCESS,E.OPER_DESC_CN AS KEY_PROCESS_CN,Min(A.STEP) as STEP, SUM(QTY) AS WIP
FROM W_INVENTORY A  WITH (NOLOCK)
WHERE EXISTS (SELECT 1 FROM S_LOOKUP B WITH (NOLOCK) WHERE A.FACILITY = B.FACILITY AND A.SITE=B.SITE AND B.ALPHA1=D.PROD_SUB_FAMILY AND B.TABLE_NAME='S_PROD_SUB_FAMILY' AND B.ALPHA2='Y')
JOIN S_PRODUCT_LINE C WITH (NOLOCK)
ON A.FACILITY = C.FACILITY AND A.SITE=C.SITE AND A.LINE_ID=C.LINE_ID
JOIN S_PRODUCT D WITH (NOLOCK)
ON A.FACILITY = D.FACILITY AND A.SITE=D.SITE AND A.PROD=D.PROD
JOIN S_OPERATION E WITH (NOLOCK) ON A.FACILITY = E.FACILITY AND A.SITE=E.SITE AND A.OPERATION=E.OPERATION AND E.DISPLAY_WIP_ON_DASHBOARD='Y'
WHERE A.FACILITY='NEO' AND A.SITE='SZ'
GROUP BY C.LINE_NAME,C.LINE_ID, D.PROD_SUB_FAMILY,D.PROD,D.PROD_DESC,E.OPER_DESC,E.OPER_DESC_CN              HAVING SUM(QTY) > 0

发现也没什么改善。

If you haven't all the things you want,be grateful for the things you don't have that you didn't want.
2011年9月5日 7:31
• sql自己知道会按照这个优化的。

这种 连接的字段最好能够是聚集索引字段，这个效率高。

family as water
2011年9月5日 7:46
• sql自己知道会按照这个优化的。

这种 连接的字段最好能够是聚集索引字段，这个效率高。

family as water
但是大部分时候都不能满足使用聚集索引作为连接条件。。。。。

If you haven't all the things you want,be grateful for the things you don't have that you didn't want.
2011年9月5日 8:15
• Should have index on join columns at least.
2011年9月5日 15:27
• 对于多表联结，sql server确实可能无法制定最优的查询计划。如果你可以确定哪些条件过滤性最强，而且对于大部分的参数条件来说都是这样，你可以通过query hint来指定sql采用什么样的执行计划。

比如联结顺序，联结方式(hash, merge, nested loop)等。但应谨慎使用query hint。

想不想时已是想，不如不想都不想。
2011年9月6日 4:23