SQL 左外连接的替代方法

SQL Alternative to left outer join

在性能方面,这是替代 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_ID、PRODUCTTYPE_ID、SUPPLIER_ID 中 Table PRODUCT 及其各自表的索引

没有!

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

  • 您正在执行多个连接而不是单个连接。单个连接应该更快。
  • 您在 on 子句中有 or。哎呀!那是性能杀手。
  • union all before join 的使用使得使用索引变得更加困难。而且统计信息很可能会关闭(虽然我不知道Firebird是否使用统计信息来优化查询)。
  • 您的复杂查询不太可能使用索引。

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

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

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)——所以这会更快。