MySQL性能 - 单个值的“IN”子句与等于(=)

时间:2012-03-29 13:33:45

标签: php mysql performance

这是一个非常简单的问题,我假设答案是“无所谓”,但无论如何我都要问......

我有一个用PHP构建的通用sql语句:

$sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')';

假设先前的有效性检查($object_ids是一个至少包含1个项目和所有数值的数组),我应该这样做吗?

if(count($object_ids) == 1) {
    $sql = 'SELECT * FROM `users` WHERE `id` = ' . array_shift($object_ids);
} else {
    $sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')';
}

或者检查count($object_ids)的开销是否值得在实际的sql语句中保存(如果有的话)?

6 个答案:

答案 0 :(得分:46)

Most of the other answers don't provide anything conclusive, just speculation. So, based on the good advice from @Namphibian's answer, I ran an EXPLAIN on some queries similar to the ones in the OP.

The results are below:


EXPLAIN for a query with = 1:

Explain for a query with <code>= 1</code>


EXPLAIN for a query with IN(1):

Explain for a query with <code>IN(1)</code>


EXPLAIN for a query with IN(1,2,3):

Explain for a query with <code>IN(1,2,3)</code>


As you can see, MySQL does optimize IN(1) to be the same as = 1 in this sort of query. @mes's answer seems to indicate that this might not always be the case with more complex queries, however.

So, for those who were too lazy to run the EXPLAIN themselves, now you know. And yes, you may want to run the EXPLAIN on your own query to be sure that it is handled this way. :-)

答案 1 :(得分:23)

MySQL语句之间没有区别,当IN只是一个元素时,MySQL优化器会将IN转换为=。不要打扰。

答案 2 :(得分:16)

在大范围的事情中,它们都不重要。与数据库通信时的网络延迟远远超过count($object_ids)开销或= vs IN开销。我认为这是一个过早优化的案例。

您应该对应用程序进行概要分析和加载测试,以了解真正的瓶颈所在。

答案 3 :(得分:8)

使用explain语句运行两个查询。这将向您展示MySQL正在做什么。你专注于MySQL优化应该是MySQL内部的查询。尝试优化执行哪个查询有点为时过早。

如果例如没有索引,这两个查询的性能都会很糟糕。 MySQL的EXPLAIN语句在这里是黄金。因此,当您进入运行缓慢的查询时,EXPLAIN语句将显示原因。

答案 4 :(得分:3)

我认为内部mysql会将IN (6)查询完全视为= 6查询,因此无需担心(顺便称之为过早优化)

答案 5 :(得分:0)

我使用explain语句运行查询,结果如下 enter image description here

显然“Equals”运算符更好,它扫描13行,“IN”扫描所有行