[英]Complex MySQL query problems and also SQL hangs
我正在尝试编写一个非常复杂的SQL查询。 要求如下:
我需要从查询中返回这些字段:
track.artist
track.title
track.seconds
track.track_id
track.relative_file
album.image_file
album.album
album.album_id
track.track_number
我可以使用以下查询选择随机轨道:
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”的表。每一行都有一个自动递增的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子句中添加了trackfilters2,而未在查询中的任何地方使用它,它也会挂起。 这让我感到奇怪。 这是正确的行为吗? 我认为在不使用数据的情况下将数据添加到FROM列表中只会使服务器获取更多数据,我不希望它挂起。
这里没有足够的信息来确定导致性能问题的原因。
但是这里有一些建议和评论。
抛弃老式的逗号语法进行联接操作,并改用JOIN关键字。 并将连接谓词重新定位到ON子句。
而且,出于天堂的缘故,对SQL进行格式化,以便尝试读取它的人可以理解它。
这里有一些问题...要返回的行在trackfilters1和trackfilters2中总是有匹配的行吗? 还是trackfilters2中可能缺少一行,并且在trackfilters1中存在匹配的行时,您仍然想返回该行? (该问题的答案确定了您是要对这些表使用外部联接还是内部联接。)
为了使大型集具有最佳性能,定义适当的索引至关重要。
使用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的输出以及定义了哪些索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.