在 2 个谓词上使用 OR 连接与 2 个单独连接每个 1 个谓词的性能比较
Performance comparison on Join with OR on 2 predicates vs 2 separate joins 1 predicate each
像这样在 ON 子句上使用带有 OR 的 2 个谓词的连接对性能有何影响:
SELECT GS.GuitarType,GD,GuitarColor
FROM Prod.Guitars GS
LEFT JOIN Prod.Guitar_Detail GD ON (GS.GuitarID = GD.GuitarID OR GS.GuitarID = GD.GuitarCatNum)
VS.像这样:
SELECT GS.GuitarType,GD,GuitarColor
FROM Prod.Guitars GS
LEFT JOIN Prod.Guitar_Detail GD ON GS.GuitarID = GD.GuitarID
LEFT JOIN Prod.Guitar_Detail GD2 ON GS.GuitarID = GD.GuitarCatNum
注意事项:
我们必须使用 LEFT JOIN 不能使用 INNER。
我已经 运行 两个查询,后者执行得更好。
还有一个问题,第二个不会return多行吧?因为它们都在同一个 table 上连接,所以它们应该只保留 GS table 对吗?
第一个查询是否必须匹配两次?或者为什么它的表现与第二个不同?
让我倒序回答。
Also another question, the 2nd won't return more rows right?
Because they're both being joined on the same table, they
should both preserve the GS table only right?
查询不同(区别在于如何处理空值),并且应该预期不同的执行时间。一切都归结为如何使用 GD.GuitarID 和 GD.GuitarCatNum。
a) 如果设置了 GD.GuitarID 并且 GD.GuitarCatNum 为 null,则查询将 return 相同的数据。
b) 如果设置了 GD.GuitarID 并且 GD.GuitarCatNum 包含与 GD.GuitarID 相同的值,则第二个查询将 return 重复行。
c) 如果 GD.GuitarID 为 null 并且设置了 GD.GuitarCatNum,则查询将 return 相同的行数,但 GD.GuitarColor 将被 return 编辑为 null。
现在,假设情况 a),执行计划如下所示:
案例 1)
SELECT
GS.GuitarType,
GD.GuitarColor
FROM
Guitars GS
LEFT JOIN Guitar_Detail GD
ON (GS.GuitarID = GD.GuitarID OR
GS.GuitarID = GD.GuitarCatNum)
Access Plan:
-----------
Total Cost: 18.3602
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
3
>NLJOIN
( 2)
18.3602
2
/-----+------\
2 1.5
TBSCAN TBSCAN
( 3) ( 4)
8.99536 9.07676
1 1
| |
2 2
TABLE: DB2INST1 TABLE: DB2INST1
GUITARS GUITAR_DETAIL
Q2 Q1
案例二)
SELECT
GS.GuitarType,
GD.GuitarColor
FROM
Guitars GS
LEFT JOIN Guitar_Detail GD
ON GS.GuitarID = GD.GuitarID
LEFT JOIN Guitar_Detail GD2
ON GS.GuitarID = GD.GuitarCatNum
Total Cost: 27.2798
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
2
>NLJOIN
( 2)
27.2798
3
/--------------+---------------\
2 1
HSJOIN< NLJOIN
( 3) ( 6)
18.0326 9.01796
2 1
/-----+------\ /-----+------\
2 2 0.5 2
TBSCAN TBSCAN TBSCAN TBSCAN
( 4) ( 5) ( 7) ( 8)
8.99536 8.99536 0.0226 8.99536
1 1 0 1
| | | |
2 2 1 2
TABLE: DB2INST1 TABLE: DB2INST1 TABFNC: SYSIBM TABLE: DB2INST1
GUITAR_DETAIL GUITARS GENROW GUITAR_DETAIL
Q2 Q1 Q4 Q6
希望对您有所帮助。
OR 通常表现不佳,尤其是在联接中。最好将数据库设计为不需要这些类型的连接。
然而,我们有时都受困于设计,在这种情况下,使用 UNION ALL 通常性能更高(如果两个连接字段相互排斥)。如果字段不互斥并且您不希望重复,则 UNION 会更慢但更好。
像这样在 ON 子句上使用带有 OR 的 2 个谓词的连接对性能有何影响:
SELECT GS.GuitarType,GD,GuitarColor
FROM Prod.Guitars GS
LEFT JOIN Prod.Guitar_Detail GD ON (GS.GuitarID = GD.GuitarID OR GS.GuitarID = GD.GuitarCatNum)
VS.像这样:
SELECT GS.GuitarType,GD,GuitarColor
FROM Prod.Guitars GS
LEFT JOIN Prod.Guitar_Detail GD ON GS.GuitarID = GD.GuitarID
LEFT JOIN Prod.Guitar_Detail GD2 ON GS.GuitarID = GD.GuitarCatNum
注意事项: 我们必须使用 LEFT JOIN 不能使用 INNER。 我已经 运行 两个查询,后者执行得更好。
还有一个问题,第二个不会return多行吧?因为它们都在同一个 table 上连接,所以它们应该只保留 GS table 对吗?
第一个查询是否必须匹配两次?或者为什么它的表现与第二个不同?
让我倒序回答。
Also another question, the 2nd won't return more rows right? Because they're both being joined on the same table, they should both preserve the GS table only right?
查询不同(区别在于如何处理空值),并且应该预期不同的执行时间。一切都归结为如何使用 GD.GuitarID 和 GD.GuitarCatNum。
a) 如果设置了 GD.GuitarID 并且 GD.GuitarCatNum 为 null,则查询将 return 相同的数据。
b) 如果设置了 GD.GuitarID 并且 GD.GuitarCatNum 包含与 GD.GuitarID 相同的值,则第二个查询将 return 重复行。
c) 如果 GD.GuitarID 为 null 并且设置了 GD.GuitarCatNum,则查询将 return 相同的行数,但 GD.GuitarColor 将被 return 编辑为 null。
现在,假设情况 a),执行计划如下所示:
案例 1)
SELECT
GS.GuitarType,
GD.GuitarColor
FROM
Guitars GS
LEFT JOIN Guitar_Detail GD
ON (GS.GuitarID = GD.GuitarID OR
GS.GuitarID = GD.GuitarCatNum)
Access Plan:
-----------
Total Cost: 18.3602
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
3
>NLJOIN
( 2)
18.3602
2
/-----+------\
2 1.5
TBSCAN TBSCAN
( 3) ( 4)
8.99536 9.07676
1 1
| |
2 2
TABLE: DB2INST1 TABLE: DB2INST1
GUITARS GUITAR_DETAIL
Q2 Q1
案例二)
SELECT
GS.GuitarType,
GD.GuitarColor
FROM
Guitars GS
LEFT JOIN Guitar_Detail GD
ON GS.GuitarID = GD.GuitarID
LEFT JOIN Guitar_Detail GD2
ON GS.GuitarID = GD.GuitarCatNum
Total Cost: 27.2798
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
2
>NLJOIN
( 2)
27.2798
3
/--------------+---------------\
2 1
HSJOIN< NLJOIN
( 3) ( 6)
18.0326 9.01796
2 1
/-----+------\ /-----+------\
2 2 0.5 2
TBSCAN TBSCAN TBSCAN TBSCAN
( 4) ( 5) ( 7) ( 8)
8.99536 8.99536 0.0226 8.99536
1 1 0 1
| | | |
2 2 1 2
TABLE: DB2INST1 TABLE: DB2INST1 TABFNC: SYSIBM TABLE: DB2INST1
GUITAR_DETAIL GUITARS GENROW GUITAR_DETAIL
Q2 Q1 Q4 Q6
希望对您有所帮助。
OR 通常表现不佳,尤其是在联接中。最好将数据库设计为不需要这些类型的连接。
然而,我们有时都受困于设计,在这种情况下,使用 UNION ALL 通常性能更高(如果两个连接字段相互排斥)。如果字段不互斥并且您不希望重复,则 UNION 会更慢但更好。