SQL左外连接的替代方案

时间:2016-11-16 21:01:32

标签: sql firebird

这是LEFT OUTER JOIN的一个很好的替代方案吗?这是最好的吗?

 SELECT a.PRODUCT_ID
    ,a.PROD_NAME
    ,a.PRODUCTTYPE_ID
    ,a.SUPPLIER_ID
    ,t.PRODTYPE_NAME
    ,s."NAME" SUPPLIER_NAME
FROM PRODUCT a
INNER JOIN (
    SELECT NULL PRODUCTTYPE_ID
        ,NULL PRODTYPE_NAME
    FROM rdb$database

    UNION ALL

    SELECT PRODUCTTYPE_ID
        ,PRODTYPE_NAME
    FROM PRODUCTTYPE
    ) t
    ON (t.PRODUCTTYPE_ID = a.PRODUCTTYPE_ID) OR (t.PRODUCTTYPE_ID IS NULL AND a.PRODUCTTYPE_ID IS NULL)
INNER JOIN (
    SELECT NULL SUPPLIER_ID
        ,NULL "NAME"
    FROM rdb$database

    UNION ALL

    SELECT SUPPLIER_ID
        ,"NAME"
    FROM SUPPLIER
    ) s
    ON (s.SUPPLIER_ID = a.SUPPLIER_ID) OR (s.SUPPLIER_ID IS NULL AND a.SUPPLIER_ID IS NULL)

表PRODUCT中的PRODUCT_ID,PRODUCTTYPE_ID,SUPPLIER_ID索引以及凭借主键和外键的各自表格

2 个答案:

答案 0 :(得分:4)

没有!

您应该使用left join。以下是您的方法(几乎全部可能)会变得更糟的一些原因:

  • 您正在进行多个连接而不是单个连接。单个连接应该更快。
  • or子句中有on。 Oy公司!那是性能杀手。
  • 在联接之前使用union all 会使索引更加困难。并且统计信息可能已关闭(尽管我不知道Firebird是否使用统计信息来优化查询)。
  • 您的复杂查询不太可能使用索引。

一个简单的left join应该使用索引并且具有更好的性能。

答案 1 :(得分:0)

如果以下查询将为您提供与您显示的相同的功能,请改为使用

SELECT a.PRODUCT_ID, a.PROD_NAME, a.PRODUCTTYPE_ID, a.SUPPLIER_ID , 
       t.PRODTYPE_NAME, s."NAME" SUPPLIER_NAME 
FROM PRODUCT a
left join PRODUCTTYPE P ON P.PRODUCTTYPE_ID=a.PRODUCTTYPE_ID 
left join SUPPLIER S ON s.SUPPLIER_ID=a.SUPPLIER_ID

你可以看到你没有工会(甚至你应该使用的UNION ALL) - 所以这会更快。