0

我有一个场景如下。

员工表

EmpId X_Id  Flag
--------------------------------
1      123     0

部门表

DeptId D.Name X_Id  Flag
----------------------------------------------
1        a     123    0
2        b     123    1

我需要编写一个基于标志获取行的查询。即,如果 EmpTable 中的 flag 为 0,则仅获取 flag 为 0 的行,如果 EmpTable 中的 flag 设置为 1,则获取所有行(标志为 0 和 1)。为此,我编写了以下查询

SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E INNER JOIN DeptTable D
ON E.X_Id = D.X_Id
AND (D.Flag = 0 or D.Flag = E.Flag)

上面的查询返回正确的行,但正如我所见,使用 OR 不是一个好主意。查询很慢。任何替代方案可以实现相同的最佳性能?

4

2 回答 2

2

唯一明显的选择是

SELECT E.EmpId,
       E.X_Id,
       D.Did,
       D.Dname
FROM   EmpTable E
       INNER JOIN DeptTable D
         ON E.X_Id = D.X_Id
            AND D.Flag = E.Flag
UNION
SELECT E.EmpId,
       E.X_Id,
       D.Did,
       D.Dname
FROM   EmpTable E
       INNER JOIN DeptTable D
         ON E.X_Id = D.X_Id
            AND D.Flag = 0 

有时重写ORasUNION可以帮助提高性能。如果这没有帮助,您将需要查看执行计划以查看是否缺少任何必需的索引。

于 2012-10-12T11:44:42.797 回答
0

一个范围,但也许值得一试。
有时连接会建立在一个索引上。
如果将其拆分,则有时它将使用单独的索引。
查看查询计划。

SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E 
JOIN DeptTable D1
  ON E.X_Id = D1.X_Id 
JOIN DeptTable D2
  ON D2.Flag = E.Flag
  OR D2.Flag = 0

SELECT E.EmpId, E.X_Id, D.Did, D.Dname
FROM EmpTable E 
JOIN DeptTable D1
  ON E.X_Id = D1.X_Id 
WHERE D2.Flag = E.Flag
   OR D2.Flag = 0
于 2012-10-12T12:59:26.053 回答