如何优化需要在列上查找才能加入的两个表的 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;