繁体   English   中英

复杂的MySQL查询问题以及SQL挂起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM