Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL性能:哪个更快?IN()与JOIN_Mysql_Sql_Performance_Join_Database Performance - Fatal编程技术网

Mysql SQL性能:哪个更快?IN()与JOIN

Mysql SQL性能:哪个更快?IN()与JOIN,mysql,sql,performance,join,database-performance,Mysql,Sql,Performance,Join,Database Performance,这是一个我从未得到明确答案的问题。在这个例子中,我使用的是MySQL 给定一组相当大的值(比如500)。在IN()子句中使用这些值搜索表是否更快: 或者通过在内存中创建临时表,用值填充临时表并将其连接到正在搜索的表: CREATE TEMPORARY TABLE `temp_table` (`field` varchar(255) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO temp_table VALUES (val

这是一个我从未得到明确答案的问题。在这个例子中,我使用的是MySQL

给定一组相当大的值(比如500)。在IN()子句中使用这些值搜索表是否更快:

或者通过在内存中创建临时表,用值填充临时表并将其连接到正在搜索的表:

CREATE TEMPORARY TABLE `temp_table` (`field` varchar(255) NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO temp_table VALUES (values)

SELECT * FROM table t1 JOIN temp_table t2 ON t1.field = t2.field
这两种方法将生成相同的结果集

我自己做了一些基本的基准测试,发现当处理500多个值时,使用临时表比使用IN()子句更快

有人能给我解释一下MySQL的内部工作原理吗?这个问题的正确答案是什么

谢谢,
Leo

来自MySql在线文档:

在(值,…)

如果所有值都是常量,则将根据expr的类型对其进行计算并排序。 然后使用二进制搜索完成对项目的搜索。这意味着 如果IN值列表完全由常量组成,则IN非常快。 否则,将根据规则进行类型转换 如第11.2节“表达式计算中的类型转换”所述, 但适用于所有论点

考虑到我认为将IN()与一组常量一起使用是有意义的,否则应该在另一个表上使用子查询

当从其他表中检索项目时,可以考虑使用UsIG而不是联接,对于大数据集

它会明显快一些。
SELECT * 
FROM table t1 
WHERE EXISTS 
      (
        SELECT * 
        FROM temp_table t2 
        WHERE t1.field = t2.field
      )

正确答案取决于许多事情

您已经完成了这项工作-如果您的基准测试告诉您使用临时表更快,那么这就是方法


如果您更改了硬件或大幅更改了架构,请记住再次进行基准测试。

请发布您的基准测试,以便对其进行验证。你们有字段索引吗?你们知道答案很大程度上取决于你们数据库的结构吗?创建临时表、填充临时表和连接临时表涉及大量CPU工作,而不是使用带IN运算符的查询。由于内存存储,IO将更快,但是InnoDB也可以将其工作数据集保存在内存中。如果您在中基于InnoDB表的主键进行搜索,它将轻而易举地击败临时表。如果您也发布了这两个字段的解释计划,那将很有趣。这两个字段都被索引,但不是主字段。我的基准测试给出了粗略的结果,表明500个值是转折点。我很想知道使用IN()子句时“幕后”发生了什么。这些都是我应该添加的MyISAM表,我不理解二进制搜索位。要使其正常工作,需要对列进行排序,并据此建立索引?那么为什么不直接从索引中查找呢?(除非它们意味着搜索使用二进制排序语义,而不是谈论实际的@Martin Smith:binary搜索(每个文档仅用于常量)当一组常量被排序时是有意义的,所以这意味着服务器进行排序,然后才执行二进制搜索。我明白了。我想的是另一种方式。所以MySQL对每个值进行全表扫描,然后在常量列表中进行二进制搜索?如果列被索引,而in子句只有几个值呢“索引搜索的效率肯定会更高?”马丁·史密斯:我不是这方面的专家,所以我可能是错的,但据我所知,当查询从表中返回可靠的数据部分时,优化器会自动应用索引搜索,但它如何确保在搜索(…)中的值时优先使用索引搜索名单?希望我已经表达了清楚的想法
SELECT * 
FROM table t1 
WHERE EXISTS 
      (
        SELECT * 
        FROM temp_table t2 
        WHERE t1.field = t2.field
      )