等于(=)和IN之间的性能差异与一个值

当我们使用等号和IN运算符具有相同的值时,SQL引擎如何不同? 执行时间是否改变?

第一个使用平等检查运算符

WHERE column_value = 'All' 

第二个使用OR运算符和单值

 WHERE column_value IN ('All') 

SQL引擎是否将IN更改为=如果只有一个值?

MySQL和PostgreSQL中有没有区别?

这两个语句之间没有区别,当IN只有一个元素时,优化器会将IN转换为=

虽然当你有这样的问题时,只要运行这两个语句,运行他们的执行计划,看看不同之处。 在这里 – 你不会find任何。

在网上一个大的search之后,我发现了一个关于SQL的文档来支持这个(我认为它适用于所有的DBMS):

如果括号内只有一个值,这个表示就相当于

WHERE“column_name”=“value1

这里是文档的链接 。

下面是Oracle中两个查询的执行计划(大多数DBMS将处理这个):

 EXPLAIN PLAN FOR select * from dim_employees t where t.identity_number = '123456789' Plan hash value: 2312174735 ----------------------------------------------------- | Id | Operation | Name | ----------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES | | 2 | INDEX UNIQUE SCAN | SYS_C0029838 | ----------------------------------------------------- 

对于IN()

 EXPLAIN PLAN FOR select * from dim_employees t where t.identity_number in('123456789'); Plan hash value: 2312174735 ----------------------------------------------------- | Id | Operation | Name | ----------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | TABLE ACCESS BY INDEX ROWID| DIM_EMPLOYEES | | 2 | INDEX UNIQUE SCAN | SYS_C0029838 | ----------------------------------------------------- 

正如你所看到的,两者是相同的。 这是一个索引列。 同样适用于无索引的列(只是全表扫描)。

当您使用单个值时,没有区别。 如果你要检查表扫描,索引扫描或索引查找上述两个查询,你会发现这两个查询没有区别。

在Mysql和PostgresSQL中有没有什么区别?

不,它在两个引擎上没有任何区别( Infact对于大多数数据库(包括SQL Server,Oracle等 )都是一样的)。 两个引擎都将IN转换为=

实际上没有太大的区别,但是如果column_value被编入索引, IN运算符可能不会将其作为索引读取。

遇到这个问题一次,所以要小心。

教一个人钓鱼,等等。以下是如何看你自己的查询的变化:

 mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id = "AMH"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sentence type: ref possible_keys: sentence_lang_id key: sentence_lang_id key_len: 153 ref: const rows: 442 Extra: Using where 

让我们以另一种方式尝试:

 mysql> EXPLAIN SELECT * FROM sentence WHERE sentence_lang_id in ("AMH")\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sentence type: ref possible_keys: sentence_lang_id key: sentence_lang_id key_len: 153 ref: const rows: 442 Extra: Using where 

你可以在这里阅读关于如何解释mysql EXPLAIN请求的结果。 现在请注意,我们对两个查询都得到了相同的输出:完全相同的“执行计划”被生成。 type行告诉我们查询使用非唯一索引(在这个例子中是一个外键), ref行告诉我们查询是通过比较一个常量和这个索引来执行的。

对于单个IN子句,没有区别..下面是演示使用EMPS表我有..

 select * from emps where empid in (1) select * from emps where empid=1 

执行计划中的第一个查询的谓词:

 [PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0) 

执行计划中第二个查询的谓词:

 [PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0) 

如果IN子句中有多个值,最好将它们转换为连接

只是添加一个不同的视angular,rdbms系统的要点之一就是他们会为你重写你的查询,并为这个查询和所有等价的查询select最好的执行计划。 这意味着只要两个查询在逻辑上相同,就应该始终在给定的rdbms上生成相同的执行计划。

也就是说,许多查询是相同的(相同的结果集),但只是因为数据库本身没有意识到的约束,所以要小心这些情况(例如,对于数字1-6的标志字段,数据库不知道<3in (1,2)的相同)。 但是在一天结束的时候,如果你只是在考虑and和/ or陈述的可读性,那么你写这些东西的方式对性能没有什么影响。

您将需要在两者上运行执行计划,并查看结果。

我相信他们将有相同的执行计划,因为只有一个值放在IN()语句中时,它将与正常=符号相同。

优化器在这样的查询上没有任何不同的行为。

Interesting Posts