Mysql SQL性能:哪个更快?IN()与JOIN
这是一个我从未得到明确答案的问题。在这个例子中,我使用的是MySQL 给定一组相当大的值(比如500)。在IN()子句中使用这些值搜索表是否更快: 或者通过在内存中创建临时表,用值填充临时表并将其连接到正在搜索的表: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
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
)