Sql 使用多个外部联接的查询中的查询优化
我正在寻找优化以下SQL查询的方法。我正在使用MS SQL Server 2008。我在想,如果有任何方法来整合外部连接,它将加快速度…如果有人有任何意见,将不胜感激。谢谢Sql 使用多个外部联接的查询中的查询优化,sql,sql-server,database,sql-server-2008,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_c
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表实际上正在使用…外部联接不是问题所在。问题在于在函数中包装列
ON COALESCE (ship.property_type, '') = COALESCE (employee_station.property_type, '')
这种构造会阻止优化器制定有效的查询计划——直到运行时它才知道函数的值是什么,因此如果存在索引,它就无法使用索引
在不使用函数的情况下重写查询,优化器将能够做出更好的决策。您可以尝试加入校验和-根据我的经验,它通常比复杂条件提供更好的性能:
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
为什么左侧连接到roomtype和dp表?他们在这里什么也没做。@BobDuell:好吧,我正要问同样的问题。哦,事实上,SELECT中还有很多字段。不过为了清晰起见,我在这里排除了它们……只是让它更简洁而已。所以这些表实际上是需要的,因为数据是从它们中提取出来的……我只是没有在这里包含实际的字段。你建议我如何在没有合并函数的情况下重写查询?我想如果我删除这些函数,我会得到非常不同的结果…问题是,为什么你认为它们是必要的?我自己不使用sql server,但是,您要加入的表中是否实际有值表示为“@dido ON ship.property\u type=employee\u station.property\u type或ship.property\u type为NULL且employee\u station.property\u type为NULL或ON EXISTS SELECT employee\u station.property\u type intersection SELECT ship.property\u type see Bob”的行?它们可能有很多NULL值数据滴滴-没有神奇的解决办法。如果这是我的代码,我想我要做的第一件事就是将数据提取到临时表中,并在加入之前进行清理,比如用某种值替换NULL。这可能会变得复杂。当然,最好的做法是不允许任何类型的键值都可以为NULL的设计,但我们通常会继承它们。嗯,你是说我们应该重新构造表,也许创建一个存储过程,用一个值替换NULL,这样我就可以去掉COALESCE函数了?这是一个想法,但不确定管理层是否会同意。。。。。。最后但并非最不重要的一点:为什么房间和员工站表没有员工id参考这将使您的查询更简单、更快捷,因为这是不推荐使用的,它也不会工作。