如何优化需要在列上查找才能加入的两个表的 JOIN?
How to optimize a JOIN of two tables that require lookups on the column to join on?
我正在对两个 table 进行简单的 INNER JOIN,附加要求是每个 table 必须首先与单独的 1:n table 连接才能获得正确的连接值。用一个简单的例子来说明,我有三个 tables UserInstalls (UserId, InstallDate), UserConversion (UserId, ConversionDate), 和UserAccounts(用户 ID、帐户 ID)。我想要 (AccountId、InstallDate、ConversionDate) 的最终结果。
UserInstalls
+--------+-------------+
| UserId | InstallDate |
+--------+-------------+
| 1 | 2015-01-11 |
| 2 | 2015-03-21 |
| 3 | 2015-02-05 |
| 4 | 2014-06-01 |
| 5 | 2014-01-23 |
| 6 | 2015-02-14 |
+--------+-------------+
UserConversion
+--------+----------------+
| UserId | ConversionDate |
+--------+----------------+
| 7 | 2015-01-15 |
| 8 | 2015-03-03 |
| 9 | 2015-08-01 |
| 10 | 2015-01-02 |
| 11 | 2014-01-24 |
| 12 | 2015-02-17 |
+--------+----------------+
UserAccounts
+--------+-----------+
| UserId | AccountId |
+--------+-----------+
| 1 | 1 |
| 7 | 1 |
| 2 | 2 |
| 8 | 2 |
| 3 | 3 |
| 9 | 3 |
| 4 | 4 |
| 10 | 4 |
| 5 | 5 |
| 11 | 5 |
| 6 | 6 |
| 12 | 6 |
+--------+-----------+
我可以简单地使用子查询来查找 AccountID,然后加入每个子查询的结果。在这种微不足道的情况下,这很好用。在涉及(10,000 多行)的实际应用程序中,这效率不高,我 运行 进入假脱机限制。
SELECT x.AccountID, InstallDate, ConversionDate
FROM (SELECT AccountID, InstallDate FROM UserInstalls
JOIN UserAccounts
ON UserInstalls.UserId = UserAccounts.UserId) x
JOIN (SELECT AccountID, ConversionDate FROM UserConversion
JOIN UserAccounts
UserConversion.UserId = UserAccounts.UserId) y
ON x.AccountId = y.AccountId;
有什么想法可以在不使用子查询或通过脚本创建多个 table 的情况下执行此操作吗?交叉连接?关系划分?
谢谢!
您应该能够在没有子查询的情况下将表连接在一起:
SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate
FROM UserAccounts ua1
JOIN UserInstalls ui on ua1.UserId = ui.UserId
JOIN UserAccounts ua2 on ua1.AccountID = ua2.AccountID
JOIN UserConversion uc on uc.UserId = ua2.UserId
您需要左连接,但从用户帐户 table 作为根开始...
select
UA.AccountID,
MAX( UI.InstallDate ) as AccountInstalled,
MAX( UC.ConversionDate ) as ConversionDate
from
UserAccounts UA
LEFT JOIN UserInstalls UI
on UA.UserID = UI.UserID
LEFT JOIN UserConversion UC
on UA.UserID = UC.UserID
group by
UA.AccountID
帐户分组基本上会从任何一方查看符合加入条件的分组。您现在每人一行,以及各自的安装和转换日期。
请检查下面的查询,如果没有得到所需的结果,请创建一个 sqlfiddle 以便我检查问题。
SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate
FROM UserInstalls ui
JOIN UserAccounts ua ON ui.UserId=ua.UserId
JOIN UserConversion uc ON ui.UserId=uc.UserId
JOIN UserAccounts ua1 ON ua.AccountId=ua1.AccountId;
我正在对两个 table 进行简单的 INNER JOIN,附加要求是每个 table 必须首先与单独的 1:n table 连接才能获得正确的连接值。用一个简单的例子来说明,我有三个 tables UserInstalls (UserId, InstallDate), UserConversion (UserId, ConversionDate), 和UserAccounts(用户 ID、帐户 ID)。我想要 (AccountId、InstallDate、ConversionDate) 的最终结果。
UserInstalls +--------+-------------+ | UserId | InstallDate | +--------+-------------+ | 1 | 2015-01-11 | | 2 | 2015-03-21 | | 3 | 2015-02-05 | | 4 | 2014-06-01 | | 5 | 2014-01-23 | | 6 | 2015-02-14 | +--------+-------------+
UserConversion +--------+----------------+ | UserId | ConversionDate | +--------+----------------+ | 7 | 2015-01-15 | | 8 | 2015-03-03 | | 9 | 2015-08-01 | | 10 | 2015-01-02 | | 11 | 2014-01-24 | | 12 | 2015-02-17 | +--------+----------------+
UserAccounts +--------+-----------+ | UserId | AccountId | +--------+-----------+ | 1 | 1 | | 7 | 1 | | 2 | 2 | | 8 | 2 | | 3 | 3 | | 9 | 3 | | 4 | 4 | | 10 | 4 | | 5 | 5 | | 11 | 5 | | 6 | 6 | | 12 | 6 | +--------+-----------+
我可以简单地使用子查询来查找 AccountID,然后加入每个子查询的结果。在这种微不足道的情况下,这很好用。在涉及(10,000 多行)的实际应用程序中,这效率不高,我 运行 进入假脱机限制。
SELECT x.AccountID, InstallDate, ConversionDate
FROM (SELECT AccountID, InstallDate FROM UserInstalls
JOIN UserAccounts
ON UserInstalls.UserId = UserAccounts.UserId) x
JOIN (SELECT AccountID, ConversionDate FROM UserConversion
JOIN UserAccounts
UserConversion.UserId = UserAccounts.UserId) y
ON x.AccountId = y.AccountId;
有什么想法可以在不使用子查询或通过脚本创建多个 table 的情况下执行此操作吗?交叉连接?关系划分?
谢谢!
您应该能够在没有子查询的情况下将表连接在一起:
SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate
FROM UserAccounts ua1
JOIN UserInstalls ui on ua1.UserId = ui.UserId
JOIN UserAccounts ua2 on ua1.AccountID = ua2.AccountID
JOIN UserConversion uc on uc.UserId = ua2.UserId
您需要左连接,但从用户帐户 table 作为根开始...
select
UA.AccountID,
MAX( UI.InstallDate ) as AccountInstalled,
MAX( UC.ConversionDate ) as ConversionDate
from
UserAccounts UA
LEFT JOIN UserInstalls UI
on UA.UserID = UI.UserID
LEFT JOIN UserConversion UC
on UA.UserID = UC.UserID
group by
UA.AccountID
帐户分组基本上会从任何一方查看符合加入条件的分组。您现在每人一行,以及各自的安装和转换日期。
请检查下面的查询,如果没有得到所需的结果,请创建一个 sqlfiddle 以便我检查问题。
SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate
FROM UserInstalls ui
JOIN UserAccounts ua ON ui.UserId=ua.UserId
JOIN UserConversion uc ON ui.UserId=uc.UserId
JOIN UserAccounts ua1 ON ua.AccountId=ua1.AccountId;