MySQL&;性能:使用';在';或';加入';?

MySQL&;性能:使用';在';或';加入';?,mysql,performance,Mysql,Performance,我有一张代码图片,可以通过ID在数据库中查找一些CD。这是使用“in”条件完成的: (1) SELECT * FROM album WHERE id IN (?,?,?,?,?) 下一步是获取与这些相册关联的曲目。我通过稍微修改“base”查询来实现这一点 (2) SELECT track.* FROM album LEFT JOIN track ON track.album_id = album.id WHERE album.id IN(?,?,?,?,?) 现在,我有了专辑和曲目。但

我有一张代码图片,可以通过ID在数据库中查找一些CD。这是使用“in”条件完成的:

(1) SELECT * FROM album WHERE id IN (?,?,?,?,?)
下一步是获取与这些相册关联的曲目。我通过稍微修改“base”查询来实现这一点

(2) SELECT track.* FROM album 
LEFT JOIN track ON track.album_id = album.id 
WHERE album.id IN(?,?,?,?,?)
现在,我有了专辑和曲目。但是,我需要加载曲目的作曲家详细信息。出于几个原因,我不能与上面的查询一起执行,所以我需要单独执行

我可以做的是根据我得到的曲目查找作曲家,在这里我将使用曲目ID并根据这些曲目ID在Composer表中查找作曲家。或者,我可以进一步修改“base”查询,并与composers表再进行一次连接。然而;这里是否有一条(关于性能)的一般规则可以轻易地指出其中一个查询是有利的?我已经做了一点测试,但我做的规模太小了,我真的看不出有什么不同

(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 (?,...);

作为记录:我已经在所有条件和联接列上建立了索引。

没有理由在查询3中使用
左联接(很高兴为它们编号),因为您只关心编写器。(通常,外部联接速度较慢。)

您不需要加入查询3中的albums表-只需使用
track.album\u id
中的
。(我想你不会担心专辑丢失的流氓曲目。)

你提到你有各种各样的索引。但请记住,MySQL在每个查询中只能对每个表使用一个索引。所以,如果你有多个东西要检查,你必须做一个复合索引

令人惊讶的是,执行连接通常比执行大型IN语句快,这是因为IN中的值没有索引,所以MySQL无法对它们执行索引连接。但这只适用于很多值,因为其中的一小部分在中使用可能会更快


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

您能够在workbench中运行这两个查询,然后比较结果吗?一般规则是您应该始终
连接
。您有多少个曲目ID?sql字符串可能会变得非常大。您好,我们可能会讨论5个相册,每个相册有100首曲目,因此在查询中很容易会有500首曲目ID…谢谢您的回答。在查询中看到100-500个跟踪ID并不少见……因此可能很容易找到很多。关于额外的连接(在第3项中)…我不能删除它,因为我的代码重复使用查询并修改它们以获取相关数据。我需要这样做,因为查询可能会有很大的变化,而且我无法真正预测“基本”查询将是什么样子。如果您使用这样的外部联接,除了一些完全空白的行之外,您必须用前端语言过滤掉它们。有了500个ID,你就不用动脑筋了:使用连接。