复杂的 MySQL 查询问题和 SQL 挂起
Complex MySQL query problems and also SQL hangs
我正在尝试编写一个非常复杂的 SQL 查询。要求如下:
我需要 return 来自查询的这些字段:
track.artist
track.title
track.seconds
track.track_id
track.relative_file
album.image_file
album.album
album.album_id
track.track_number
我可以使用以下查询 select 随机曲目:
select
track.artist, track.title, track.seconds, track.track_id,
track.relative_file, album.image_file, album.album,
album.album_id, track.track_number
FROM
track, album
WHERE
album.album_id = track.album_id
ORDER BY RAND() limit 10;
这就是我遇到问题的地方。我还有一个名为 "trackfilters1" 到 "trackfilters10" 的 table 每行都有一个自动递增的 ID 字段。因此,第 10 行是 album_id 10 的数据。这些字段填充有 1 和 0。例如,专辑 #10 有 10 首曲目,如果所有曲目都包含在搜索中,则 trackfilters1.flags 将包含“1111111111”。如果要排除轨道 10,则它将包含“1111111110”
我的问题是包括这个条款。
我提出的最新查询如下:
select
track.artist, track.title, track.seconds,
track.track_id, track.relative_file, album.image_file,
album.album, album.album_id, track.track_number
FROM
track, album, trackfilters1, trackfilters2
WHERE
album.album_id = track.album_id
AND
( (album.album_id = trackfilters1.id)
OR
(album.album_id=trackfilters2.id) )
AND
( (mid(trackfilters1.flags, track.track_number,1) = 1)
OR
( mid(trackfilters2.flags, track.track_number,1) = 1))
ORDER BY RAND() limit 2;
然而,这会导致 SQL 挂起。我假设我做错了什么。有人知道它是什么吗?如果有更简单的方法来实现我的最终结果,我会乐于接受建议,如果有更好的方法来完成此操作,我不会着手修复损坏的查询。
此外,在我的试验中,我注意到当我有一个工作查询并在 FROM 子句中添加 say trackfilters2 而没有在查询中的任何地方使用它时,它也会挂起。这让我想知道。这是正确的行为吗?我认为在不使用数据的情况下添加到 FROM 列表只会使服务器获取更多数据,我不会期望它挂起。
此处没有足够的信息来确定导致性能问题的原因。
但这里有一些建议和意见。
放弃连接操作的老式逗号语法,改用 JOIN 关键字。并将连接谓词重新定位到 ON 子句。
看在上帝的分上,格式化 SQL 以便试图阅读它的人能够破译它。
这里有一些问题...在 trackfilters1 和 trackfilters2 中是否总是有一个匹配的行与您想要 return 的行匹配?或者 trackfilters2 中可能缺少一行,如果 trackfilters1 中有匹配的行,您仍然想要 return 该行? (该问题的答案决定了您是要对这些表使用外部联接还是内部联接。)
为了在大型数据集上获得最佳性能,定义适当的索引至关重要。
使用EXPLAIN
查看执行计划。
我建议您尝试这样编写查询:
SELECT track.artist
, track.title
, track.seconds
, track.track_id
, track.relative_file
, album.image_file
, album.album
, album.album_id
, track.track_number
FROM track
JOIN album
ON album.album_id = track.album_id
LEFT
JOIN trackfilters1
ON trackfilters1.id = album.album_id
LEFT
JOIN trackfilters2
ON trackfilters2.id = album.album_id
WHERE MID(trackfilters1.flags, track.track_number, 1) = '1'
OR MID(trackfilters2.flags, track.track_number, 1) = '1'
ORDER BY RAND()
LIMIT 2
如果您需要性能方面的帮助,请提供 EXPLAIN 的输出以及定义的索引。
我正在尝试编写一个非常复杂的 SQL 查询。要求如下:
我需要 return 来自查询的这些字段:
track.artist
track.title
track.seconds
track.track_id
track.relative_file
album.image_file
album.album
album.album_id
track.track_number
我可以使用以下查询 select 随机曲目:
select
track.artist, track.title, track.seconds, track.track_id,
track.relative_file, album.image_file, album.album,
album.album_id, track.track_number
FROM
track, album
WHERE
album.album_id = track.album_id
ORDER BY RAND() limit 10;
这就是我遇到问题的地方。我还有一个名为 "trackfilters1" 到 "trackfilters10" 的 table 每行都有一个自动递增的 ID 字段。因此,第 10 行是 album_id 10 的数据。这些字段填充有 1 和 0。例如,专辑 #10 有 10 首曲目,如果所有曲目都包含在搜索中,则 trackfilters1.flags 将包含“1111111111”。如果要排除轨道 10,则它将包含“1111111110”
我的问题是包括这个条款。
我提出的最新查询如下:
select
track.artist, track.title, track.seconds,
track.track_id, track.relative_file, album.image_file,
album.album, album.album_id, track.track_number
FROM
track, album, trackfilters1, trackfilters2
WHERE
album.album_id = track.album_id
AND
( (album.album_id = trackfilters1.id)
OR
(album.album_id=trackfilters2.id) )
AND
( (mid(trackfilters1.flags, track.track_number,1) = 1)
OR
( mid(trackfilters2.flags, track.track_number,1) = 1))
ORDER BY RAND() limit 2;
然而,这会导致 SQL 挂起。我假设我做错了什么。有人知道它是什么吗?如果有更简单的方法来实现我的最终结果,我会乐于接受建议,如果有更好的方法来完成此操作,我不会着手修复损坏的查询。
此外,在我的试验中,我注意到当我有一个工作查询并在 FROM 子句中添加 say trackfilters2 而没有在查询中的任何地方使用它时,它也会挂起。这让我想知道。这是正确的行为吗?我认为在不使用数据的情况下添加到 FROM 列表只会使服务器获取更多数据,我不会期望它挂起。
此处没有足够的信息来确定导致性能问题的原因。
但这里有一些建议和意见。
放弃连接操作的老式逗号语法,改用 JOIN 关键字。并将连接谓词重新定位到 ON 子句。
看在上帝的分上,格式化 SQL 以便试图阅读它的人能够破译它。
这里有一些问题...在 trackfilters1 和 trackfilters2 中是否总是有一个匹配的行与您想要 return 的行匹配?或者 trackfilters2 中可能缺少一行,如果 trackfilters1 中有匹配的行,您仍然想要 return 该行? (该问题的答案决定了您是要对这些表使用外部联接还是内部联接。)
为了在大型数据集上获得最佳性能,定义适当的索引至关重要。
使用EXPLAIN
查看执行计划。
我建议您尝试这样编写查询:
SELECT track.artist
, track.title
, track.seconds
, track.track_id
, track.relative_file
, album.image_file
, album.album
, album.album_id
, track.track_number
FROM track
JOIN album
ON album.album_id = track.album_id
LEFT
JOIN trackfilters1
ON trackfilters1.id = album.album_id
LEFT
JOIN trackfilters2
ON trackfilters2.id = album.album_id
WHERE MID(trackfilters1.flags, track.track_number, 1) = '1'
OR MID(trackfilters2.flags, track.track_number, 1) = '1'
ORDER BY RAND()
LIMIT 2
如果您需要性能方面的帮助,请提供 EXPLAIN 的输出以及定义的索引。