使用相同条件对同一列进行多个联接操作。有没有办法提高效率?

问题描述 投票:0回答:1

在 SQL 中,我有多个表,例如 T1、T2、T3、T4、X1、X2、X3、X4

假设桌子尺寸为

 T1 > T2 > T3 > T4
 X1 > X3 > X4 > X4

我们有

SELECT 
    T1.a, T2.b, T3.c, T4.d 
FROM
    T1 
JOIN 
    T2 ON T1.userid = T2.userid AND T1.catch = T2.catch 
JOIN
    T3 ON T2.userid = T3.userid AND T2.catch = T3.catch 
JOIN
    T4 ON T3.userid = T4.userid AND T3.catch = T4.catch

假设列a仅存在于T1中,b仅存在于T2中,c仅存在于T3中,d仅存在于T4中。我们有多个具有相同条件的连接操作(列 userid,catch 相等)

另外,对于 X1、X2、X3、X4,我们有

 SELECT X1.f, X2.g, X3.h, X4.k 
 FROM X1 
 JOIN X2 ON X1.userid = X2.userid AND X1.time >= X2.time 
 JOIN X3 ON X2.userid = X3.userid AND X2.time >= X3.time 
 JOIN X4 ON X3.userid = X4.userid AND X3.time >= X4.time

假设列f仅存在于X1中,g仅存在于X2中,h仅存在于X3中,k仅存在于X4中。我们有多个具有相同条件的联接操作(列 userid 相等,当前表的时间 >= 下一个联接表的时间)。

我们在同一列上有多个具有相同条件的连接操作。

有什么办法可以让这些查询更便宜吗?如果我们想最大限度地减少查询时间,最好的解决方案是什么?

任何中间表都有助于优化整体查询?例如,如果我以相同的条件将 T1 与 T2 连接并称为 J1,将 T3 与 T4 连接并称为 J2,然后将 J1 与 J2 连接,会更快吗?

我听说索引可以有所帮助,但不确定如何在这里应用它。 (有例子吗)?

尝试创建一些中间表或减少连接操作的方法,但无法想出任何好的方法。想检查是否有任何索引方法会很好。

sql optimization
1个回答
0
投票

同一列上的等值连接

在同一列上连接三个或更多表时,有两种情况:

  • 所有表格或除一张表格外的所有表格都是 1:1 相关的。有时我们这样做是为了对属于同一条目的不同数据部分给予不同的授权(例如,将供应商的地址数据与其合同数据分开,因为不同的部门维护这些不同的数据部分)。在这种情况下,我们自愿进行这种分离,但代价是(稍微)更长的查询时间。对运行时间的影响通常并不严重,因为我们当然会索引这些列上的所有表。
  • 尽管在相同的列上进行连接,但表是 1:n 甚至 m:n 相关的。因此我们创建了一个笛卡尔连接。例如。将产品的供应商和产品的买家都加入到产品中,从而将每个供应商与每个买家结合在一起。如您所见,这是一种非常罕见的情况,因此我们应该可以接受在这些罕见情况下长时间运行。

您的第二个查询不使用等连接,也会导致这样的笛卡尔结果,甚至建立一些历史记录。这个查询看起来很奇怪,应该是一个极其特殊的情况,您可能只运行一次或非常非常少。

加快查询速度

只要查询写得正确,就像您的查询一样,我们就不会通过重写来加快查询速度。我们只需要确保数据库本身支持此类查询。这是通过提供适当的索引甚至对表进行分区来完成的。

对于您的查询,您需要每个表上的连接列上的索引。因此,DBMS 可以快速找到属于一起的行并访问有问题的表行。或者您甚至还提供包含所选列的覆盖索引。因此,DBMS 在索引中找到该信息,而不必访问表行。

索引将从

ON
WHERE
子句中使用的列开始,然后添加其他列。例如:

CREATE INDEX idx1t1 ON t1 (userid, catch, a);
CREATE INDEX idx1x1 ON x1 (userid, time, f);

或者,如果您的数据库支持语法,那就更好了:

CREATE INDEX idx1t1 ON t1 (userid, catch) INCLUDE (a);
CREATE INDEX idx1x1 ON x1 (userid, time) INCLUDE (f);

但是,如果查询写得不好,有时会在生成笛卡尔积的连接中看到这种情况,并对其进行处理

SELECT DISTINCT
以消除查询本身产生的重复项,那么该查询就必须得到调整。有时这是关于使用
EXISTS
IN
而不是连接,有时是关于连接之前的聚合而不是相反,有时横向连接提供了一个很好的解决方案。但在您所显示的查询中,情况并非如此。

不,使用临时表通常会减慢速度而不是加快速度。它们的好处是可以使流程更加清晰,因为任务被分为单独的查询。但每个查询都需要时间,总时间通常比使用单个查询执行同一任务要长。

© www.soinside.com 2019 - 2024. All rights reserved.