3

我有一段代码可以通过它们的 ID 在数据库中查找几张 CD。这是使用“IN”条件完成的:

(1) SELECT * FROM album WHERE id IN (?,?,?,?,?)

下一步是获取与这些专辑相关的曲目。我通过稍微修改“基本”查询来做到这一点。

(2) SELECT track.* FROM album 
LEFT JOIN track ON track.album_id = album.id 
WHERE album.id IN(?,?,?,?,?)

现在,我有专辑和曲目。但是,我需要加载曲目的作曲家详细信息。由于几个原因,我不能与上面的查询一起做,所以我需要单独做。

我可以做的是根据我拥有的曲目查找作曲家,我将使用曲目 ID 并根据这些曲目 ID 在作曲家表中查找作曲家。或者,我可以进一步修改“基本”查询,并与作曲家表再进行一次连接。然而; 这里是否有一个一般规则(关于性能)很容易指出其中一个查询是有利的?我已经进行了一些测试,但是我已经在如此小的范围内完成了它,以至于我真的看不出任何区别......

(3) SELECT composer.* FROM album 
LEFT JOIN track ON track.album_id = album.id
LEFT JOIN composer ON composer.track_id = track.id
WHERE album.id IN (?,?,?,?,?)

...或者...

[get track ids from query (2)]

(4) SELECT composer.* FROM composer
WHERE composer.track_id IN (?,...);

作为记录:我已经在所有标准和连接列上建立了索引。

4

1 回答 1

5

没有理由LEFT JOIN在查询 3 中使用(你们为它们编号),因为您只关心作曲家。(通常外部连接较慢。)

您不需要在查询 3 中加入专辑表 - 只需使用INon track.album_id。(我假设您并不担心缺少专辑的流氓曲目。)

您提到您对各种事物都有索引。但请记住,MySQL 每次查询每个表只能使用一个索引。因此,如果您要检查多项内容,则必须创建一个复合索引。

令人惊讶的是,执行连接通常比大型 IN 语句更快,这是因为 IN 中的值没有索引,因此 MySQL 无法对它们执行索引连接。但这仅适用于大量值 - 对于少数使用 IN 的值可能会更快。

就个人而言,我会使用 JOIN 方法,直到您看到此查询成为问题为止。(只有当您有一些非常复杂的条件要检查时才会发生这种情况,这样做两次可能会变慢)。连接是更简单的代码,而且很可能会非常快——所以不要在没有特定原因的情况下让事情变得更复杂。

于 2012-08-29T07:54:06.113 回答