左连接会导致性能大幅下降。如何修复
Left join causes huge performance drop. How to fix it
我有 3 个单独的查询,当我通过左连接合并它们时,性能下降很大
知道为什么会发生这种情况或如何解决这个问题吗?
此处查询
第一次查询
SELECT MONEY,
AccountLevel,
BadgeCount,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount
FROM table_2
WHERE table_2.UserId = 465903
第二次查询
SELECT COUNT(DISTINCT table_1.PokemonId) AS PokedexOwnage
FROM table_1 WHERE UserId = 465903
第三次查询
SELECT COUNT(*) AS PokedexEvent
FROM table_3 WHERE UserId = 465903
这是我将所有 3 个合并为一个的解决方案
SELECT MONEY,
AccountLevel,
BadgeCount,
COUNT(DISTINCT table_1.PokemonId) AS PokedexOwnage,
COUNT(DISTINCT table_3.PokemonId) AS PokedexEvent,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount
FROM table_2
LEFT JOIN table_1 ON table_1.UserId = table_2.UserId
LEFT JOIN table_3 ON table_3.UserId = table_2.UserId
WHERE table_2.UserId = 465903
GROUP BY AccountLevel,
BadgeCount,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount,
MONEY
当我通过执行计划进行比较时,前 3 个查询相对于最后一个查询的成本为 0%
在 加入之前 聚合。一种方法是使用相关子查询:
SELECT MONEY, AccountLevel, BadgeCount, EloWin,
TournamentOfficBattleTotal, MaximumTowerLevel, NpcBattleVictoryCount,
(SELECT COUNT(DISTINCT t1.PokemonId)
FROM table_1 t1
WHERE t1.UserId = t2.UserId
) as PokedexOwnage,
(SELECT COUNT(*)
FROM table_3 t3
WHERE t1.UserId = t3.UserId
) as PokedexEvent
FROM table_2 t2
WHERE t2.UserId = 465903;
这可能没问题。但为了获得更好的性能,请确保您在 table_2(UserId, PokemonId)
和 table_3(UserId)
.
上有索引
我有 3 个单独的查询,当我通过左连接合并它们时,性能下降很大
知道为什么会发生这种情况或如何解决这个问题吗?
此处查询
第一次查询
SELECT MONEY,
AccountLevel,
BadgeCount,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount
FROM table_2
WHERE table_2.UserId = 465903
第二次查询
SELECT COUNT(DISTINCT table_1.PokemonId) AS PokedexOwnage
FROM table_1 WHERE UserId = 465903
第三次查询
SELECT COUNT(*) AS PokedexEvent
FROM table_3 WHERE UserId = 465903
这是我将所有 3 个合并为一个的解决方案
SELECT MONEY,
AccountLevel,
BadgeCount,
COUNT(DISTINCT table_1.PokemonId) AS PokedexOwnage,
COUNT(DISTINCT table_3.PokemonId) AS PokedexEvent,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount
FROM table_2
LEFT JOIN table_1 ON table_1.UserId = table_2.UserId
LEFT JOIN table_3 ON table_3.UserId = table_2.UserId
WHERE table_2.UserId = 465903
GROUP BY AccountLevel,
BadgeCount,
EloWin,
TournamentOfficBattleTotal,
MaximumTowerLevel,
NpcBattleVictoryCount,
MONEY
当我通过执行计划进行比较时,前 3 个查询相对于最后一个查询的成本为 0%
在 加入之前 聚合。一种方法是使用相关子查询:
SELECT MONEY, AccountLevel, BadgeCount, EloWin,
TournamentOfficBattleTotal, MaximumTowerLevel, NpcBattleVictoryCount,
(SELECT COUNT(DISTINCT t1.PokemonId)
FROM table_1 t1
WHERE t1.UserId = t2.UserId
) as PokedexOwnage,
(SELECT COUNT(*)
FROM table_3 t3
WHERE t1.UserId = t3.UserId
) as PokedexEvent
FROM table_2 t2
WHERE t2.UserId = 465903;
这可能没问题。但为了获得更好的性能,请确保您在 table_2(UserId, PokemonId)
和 table_3(UserId)
.