在 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 连接,会更快吗?
我听说索引可以有所帮助,但不确定如何在这里应用它。 (有例子吗)?
尝试创建一些中间表或减少连接操作的方法,但无法想出任何好的方法。想检查是否有任何索引方法会很好。
在同一列上连接三个或更多表时,有两种情况:
您的第二个查询不使用等连接,也会导致这样的笛卡尔结果,甚至建立一些历史记录。这个查询看起来很奇怪,应该是一个极其特殊的情况,您可能只运行一次或非常非常少。
只要查询写得正确,就像您的查询一样,我们就不会通过重写来加快查询速度。我们只需要确保数据库本身支持此类查询。这是通过提供适当的索引甚至对表进行分区来完成的。
对于您的查询,您需要每个表上的连接列上的索引。因此,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
而不是连接,有时是关于连接之前的聚合而不是相反,有时横向连接提供了一个很好的解决方案。但在您所显示的查询中,情况并非如此。
不,使用临时表通常会减慢速度而不是加快速度。它们的好处是可以使流程更加清晰,因为任务被分为单独的查询。但每个查询都需要时间,总时间通常比使用单个查询执行同一任务要长。