Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用多个外部联接的查询中的查询优化_Sql_Sql Server_Database_Sql Server 2008 - Fatal编程技术网

Sql 使用多个外部联接的查询中的查询优化

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

我正在寻找优化以下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表实际上正在使用…

外部联接不是问题所在。问题在于在函数中包装列

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参考这将使您的查询更简单、更快捷,因为这是不推荐使用的,它也不会工作。