查询中的查询优化使用了许多外连接

时间:2012-12-18 20:34:55

标签: sql sql-server database sql-server-2008

我正在寻找优化以下SQL查询的方法。我正在使用MS SQL Server 2008.我在想是否有任何方法来整合外连接它会加快速度......如果有人有任何输入,那将非常感激。感谢

SELECT employee.employee_id,
   coalesce (room.ship_id, ship.ship_id) AS ship_id,
   SUBSTRING (employee.service_id, 0, 6) AS cost_code,
   employee_station.room_cat AS nws_room_cat
FROM employee
   LEFT OUTER JOIN room
      ON     employee.ship_id = room.ship_id
         AND employee.floor_id = room.floor_id
         AND employee.room_id = room.room_id
   LEFT OUTER JOIN ship
      ON employee.ship_id = ship.ship_id
   LEFT OUTER JOIN employee_station
      ON COALESCE (ship.property_type, '') =
            COALESCE (employee_station.property_type, '')
         AND COALESCE (room.work_center_id, '') = COALESCE (employee_station.work_center_id, '')
         AND COALESCE (employee.pay_plan, '') =
                COALESCE (employee_station.pay_plan, '')
         AND COALESCE (employee.employee_type, '') =
                COALESCE (employee_station.employee_type, '')
         AND COALESCE (SUBSTRING (employee.service_id, 0, 6), '') =
                COALESCE (employee_station.cost_code, '')
   LEFT OUTER JOIN roomtype
      ON room.room_type = roomtype.room_type
   LEFT OUTER JOIN dp
      ON employee.service_id = dp.service_id

注意:出于清晰的目的,我故意在SELECT语句中省略了很多字段。所以roomtype和dp表实际上正在使用......

2 个答案:

答案 0 :(得分:1)

OUTER JOIN不是问题。问题在于将列包装在函数内部。

ON COALESCE (ship.property_type, '') = COALESCE (employee_station.property_type, '')

这种结构阻止优化器制定有效的查询计划 - 它不知道函数的值在运行时是什么,因此如果它们存在则无法使用索引。

在没有函数的情况下重写查询,优化器将能够做出更好的决策。

答案 1 :(得分:0)

您可以尝试加入CHECKSUMS - 根据我的经验,它通常比复杂条件提供更好的性能:

SELECT 
--columns you need
FROM employee
LEFT OUTER JOIN room
ON CHECKSUM(employee.ship_id, employee.floor_id, employee.room_id) 
= CHECKSUM(room.ship_id, room.floor_id, room.room_id)
LEFT OUTER JOIN ship
ON employee.ship_id = ship.ship_id
LEFT OUTER JOIN employee_station
ON CHECKSUM(ship.property_type, room.work_center_id, employee.pay_plan, employee.employee_type, SUBSTRING (employee.service_id, 0, 6)) 
= CHECKSUM(employee_station.property_type, employee_station.work_center_id, employee_station.pay_plan, employee_station.employee_type, employee_station.cost_code)
LEFT OUTER JOIN roomtype
ON room.room_type = roomtype.room_type
LEFT OUTER JOIN dp
ON employee.service_id = dp.service_id