来自多个 LEFT JOIN 的巨大结果集的替代方案
Alternative To Huge Result Set From Multiple LEFT JOINs
我正在寻求一些关于处理当您 LEFT JOIN 多个 table 时结果集中的行数激增的情况的建议。我知道这是预期的行为,但我想知道推荐的处理方式。我知道我可以让我的应用程序执行多个查询以减少总体返回的行数,但我正在尝试看看是否有办法让 SQL 完成大部分繁重的工作并且仍然只进行一个“回合”旅行”(例如,a la this answer)。
例子
这是我的 SQL:
SELECT al.title albumTitle
, releaseDate
, name artistName
, duration
, t.title trackTitle
, styleName
FROM album al
LEFT JOIN lu_albumartist aa ON aa.albumId = al.albumId
LEFT JOIN artist ar ON ar.artistId = aa.artistId
LEFT JOIN track t ON t.albumId = al.albumId
LEFT JOIN lu_albumstyle ast ON ast.albumId = al.albumId
LEFT JOIN style s ON s.styleId = ast.styleId
WHERE al.title LIKE '%A Love Supreme%'
这个SQL Fiddle有助于证明问题:
我正在检索有关音乐专辑的信息。 我真的只需要 11 行 就可以让我的应用填充所有字段(1 张专辑、4 位艺术家、3 首曲目、3 种风格),但是查询返回36 行。我将无法使用大多数行;例如,我不关心风格和艺术家或风格和曲目的所有排列。当我为其他事物(例如,乐器、格式、评论、曲目播放信息等)添加更多 LEFT JOINS 时,排列的数量可以扩展到 10,000s!
理想情况下,我想要一个更简洁的结果集:
超级紧凑:4 行(用这种方式读取 table 没有多大意义,尽管应用程序可以解析它)
| title | releaseDate | name | duration | title | styleName |
|----------------|----------------------------|----------------|-------------|----------------------------------------|-------------|
| A Love Supreme | 1965 | John Coltrane | 479 | Part I - Acknowledgement | Free Jazz |
| [something] | [something] | McCoy Tyner | 435 | Part II - Resolution | Hard Bop |
| [something] | [something] | Jimmy Garrison | 1060 | Part III - Pursuance / Part IV - Psalm | Modal |
| [something] | [something] | Elvin Jones | [something] | [something] | [something] |
...[something]" 只是表示值可以是任何东西;该应用程序不会关心
紧凑:11 行(对人类有意义)
| title | releaseDate | name | duration | title | styleName |
|----------------|----------------------------|----------------|----------|----------------------------------------|-----------|
| A Love Supreme | 1965 | | | | |
| | | John Coltrane | | | |
| | | McCoy Tyner | | | |
| | | Jimmy Garrison | | | |
| | | Elvin Jones | | | |
| | | | 479 | Part I - Acknowledgement | |
| | | | 435 | Part II - Resolution | |
| | | | 1060 | Part III - Pursuance / Part IV - Psalm | |
| | | | | | Free Jazz |
| | | | | | Hard Bop |
| | | | | | Modal |
与应用程序的代码可移植性、可读性和可扩展性相比,我更关心性能。
基于那个 earlier linked question,其他答案和评论建议我不应该尝试加入超过 3 tables。
- 我应该放弃这种方法吗?如果我要使用多个查询,可能会有十几个或更多。
- 我怀疑有一种方法可以使用 UNION ALL 来解决这个问题,但这是最佳实践吗?
- 我猜这是一个相对常见的问题,但我找不到好的答案或一套可遵循的准则。对于这种情况,推荐的方法是什么?
我可以告诉你第一种方法我会怎么做。
我会使用多个查询,但不是对每件事一个查询,而是对多个相关事物进行一个查询。就像您在查询中所做的那样。但我可能会删除曲目,然后使用此查询进行专辑搜索(如 discogs 以及其他提到的网站)。
如果用户随后选择了一张相册,我会在一个查询中加载多个其他相关内容。就像在一个查询中带有曲目播放信息的曲目,在另一种查询格式和乐器中等等。所以我会把相关的东西放在一起,实际上就像我会把它分组在 ui.
一如既往,我会尽可能简单。并考虑用户在一页上需要多少信息。有些东西可以懒加载,如果用户主动想看的话。
我认为不要加入超过 3 个表的建议是笼统的。想一想一对一或多对一的关系,最多返回一条记录,并且记录的数量不会越来越大。
我正在寻求一些关于处理当您 LEFT JOIN 多个 table 时结果集中的行数激增的情况的建议。我知道这是预期的行为,但我想知道推荐的处理方式。我知道我可以让我的应用程序执行多个查询以减少总体返回的行数,但我正在尝试看看是否有办法让 SQL 完成大部分繁重的工作并且仍然只进行一个“回合”旅行”(例如,a la this answer)。
例子
这是我的 SQL:
SELECT al.title albumTitle
, releaseDate
, name artistName
, duration
, t.title trackTitle
, styleName
FROM album al
LEFT JOIN lu_albumartist aa ON aa.albumId = al.albumId
LEFT JOIN artist ar ON ar.artistId = aa.artistId
LEFT JOIN track t ON t.albumId = al.albumId
LEFT JOIN lu_albumstyle ast ON ast.albumId = al.albumId
LEFT JOIN style s ON s.styleId = ast.styleId
WHERE al.title LIKE '%A Love Supreme%'
这个SQL Fiddle有助于证明问题:
我正在检索有关音乐专辑的信息。 我真的只需要 11 行 就可以让我的应用填充所有字段(1 张专辑、4 位艺术家、3 首曲目、3 种风格),但是查询返回36 行。我将无法使用大多数行;例如,我不关心风格和艺术家或风格和曲目的所有排列。当我为其他事物(例如,乐器、格式、评论、曲目播放信息等)添加更多 LEFT JOINS 时,排列的数量可以扩展到 10,000s!
理想情况下,我想要一个更简洁的结果集:
超级紧凑:4 行(用这种方式读取 table 没有多大意义,尽管应用程序可以解析它)
| title | releaseDate | name | duration | title | styleName |
|----------------|----------------------------|----------------|-------------|----------------------------------------|-------------|
| A Love Supreme | 1965 | John Coltrane | 479 | Part I - Acknowledgement | Free Jazz |
| [something] | [something] | McCoy Tyner | 435 | Part II - Resolution | Hard Bop |
| [something] | [something] | Jimmy Garrison | 1060 | Part III - Pursuance / Part IV - Psalm | Modal |
| [something] | [something] | Elvin Jones | [something] | [something] | [something] |
...[something]" 只是表示值可以是任何东西;该应用程序不会关心
紧凑:11 行(对人类有意义)
| title | releaseDate | name | duration | title | styleName |
|----------------|----------------------------|----------------|----------|----------------------------------------|-----------|
| A Love Supreme | 1965 | | | | |
| | | John Coltrane | | | |
| | | McCoy Tyner | | | |
| | | Jimmy Garrison | | | |
| | | Elvin Jones | | | |
| | | | 479 | Part I - Acknowledgement | |
| | | | 435 | Part II - Resolution | |
| | | | 1060 | Part III - Pursuance / Part IV - Psalm | |
| | | | | | Free Jazz |
| | | | | | Hard Bop |
| | | | | | Modal |
与应用程序的代码可移植性、可读性和可扩展性相比,我更关心性能。
基于那个 earlier linked question,其他答案和评论建议我不应该尝试加入超过 3 tables。
- 我应该放弃这种方法吗?如果我要使用多个查询,可能会有十几个或更多。
- 我怀疑有一种方法可以使用 UNION ALL 来解决这个问题,但这是最佳实践吗?
- 我猜这是一个相对常见的问题,但我找不到好的答案或一套可遵循的准则。对于这种情况,推荐的方法是什么?
我可以告诉你第一种方法我会怎么做。
我会使用多个查询,但不是对每件事一个查询,而是对多个相关事物进行一个查询。就像您在查询中所做的那样。但我可能会删除曲目,然后使用此查询进行专辑搜索(如 discogs 以及其他提到的网站)。
如果用户随后选择了一张相册,我会在一个查询中加载多个其他相关内容。就像在一个查询中带有曲目播放信息的曲目,在另一种查询格式和乐器中等等。所以我会把相关的东西放在一起,实际上就像我会把它分组在 ui.
一如既往,我会尽可能简单。并考虑用户在一页上需要多少信息。有些东西可以懒加载,如果用户主动想看的话。
我认为不要加入超过 3 个表的建议是笼统的。想一想一对一或多对一的关系,最多返回一条记录,并且记录的数量不会越来越大。