当我们使用等号和IN运算符具有相同的值时,SQL引擎有什么不同?执行时间是否改变?等于(=)和IN之间的性能差异与一个值
一日一使用平等检查操作
WHERE column_value = 'All'
:第二个使用OR运算符和单值
WHERE column_value IN ('All')
是否SQL引擎改变IN
到=
如果只有一个值吗?
在MySQL和PostgreSQL中有相同的区别吗?
当我们使用等号和IN运算符具有相同的值时,SQL引擎有什么不同?执行时间是否改变?等于(=)和IN之间的性能差异与一个值
一日一使用平等检查操作
WHERE column_value = 'All'
:第二个使用OR运算符和单值
WHERE column_value IN ('All')
是否SQL引擎改变IN
到=
如果只有一个值吗?
在MySQL和PostgreSQL中有相同的区别吗?
这两条语句之间没有区别,当IN
只有一个元素时,优化程序会将IN
转换为=
。
虽然当你有这样的问题时,只需运行两个语句,运行他们的执行计划并查看差异。在这里 - 你不会找到任何。
后大网上搜索,我发现了SQL文件来支持这个(我认为它适用于所有DBMS):
如果只有一个括号内的值,这称道的是相当于
WHERE “栏”=“VALUE1
Here is the link to the document。
下面是这两个查询了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 |
-----------------------------------------------------
正如你可以看到,二者相。这是一个索引列。同样适用于无索引的列(只是全表扫描)。
你对此有任何数据库的官方参考吗?我试过搜索,但没有得到。 –
@SomnathMuluk更新了答案 – sagi
@SomnathMuluk: - 我不认为有这样的MySQL官方参考。如果您发现结果之间存在任何差异,您可以创建一个测试用例并自行测试。 –
当您使用单个值时,没有区别。如果您要检查上述两个查询的表扫描,索引扫描或索引查找,您会发现两个查询之间没有区别。
在Mysql和PostgresSQL中有相同的区别吗?
不,它不会对两台发动机有什么区别(逸岸它会为大多数数据库中包括SQL服务器,Oracle等相同)。两个引擎将转换为为=
对于单个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子句多个值,最好将它们转换成连接
我已经提到过只有一个值。 –
@SomnathMuluk:仅针对一个子句进行更新 – TheGameiswar
确实没有什么大的差别,但是如果column_value已编入索引,则IN
运算符可能不会将其作为索引读取。
遇到此问题一次,所以要小心。
您需要在两者上运行执行计划并查看结果。
我相信他们将具有相同的执行计划,因为只有一个值放在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
你可以请阅读here以了解如何解释mysql EXPLAIN
请求的结果。现在请注意,我们对两个查询都得到了相同的输出:完全相同的“执行计划”生成。 type
行告诉我们查询使用非唯一索引(在这种情况下是外键),ref
行告诉我们查询是通过比较一个常数值和这个索引来执行的。
只是为了添加不同的视角,rdbms系统的要点之一就是他们会为您重写您的查询,并为该查询和所有等价的查询选择最佳执行计划。这意味着只要两个查询在逻辑上相同,应始终在给定的rdbms上生成相同的执行计划。这就是说,许多查询是等价的(相同的结果集),但仅仅是因为数据库本身并不知道的约束,所以要小心这些情况(例如,对于数字为1-6的标志字段,数据库不会不知道<3
与in (1,2)
相同)。但是在一天结束时,如果您只是在考虑and
和or
声明的易读性,那么您写入它们的方式对性能没有影响。
不要试图学习数以百万计的规则,这在某种程度上意味着你总是会写出尽可能绝对性能最好的代码。写清楚,简单,*可以理解的*代码,显然会产生正确的结果。设定绩效目标。然后*测量*您的代码的性能。如果它充分执行,继续前进。只有在表现不佳的情况下,你才应该花更多时间。在那个时候,尝试像你的问题那样的微小变化,然后再次测量*就很简单。也许一个比另一个更快,但*它是否会产生显着差异*? –
同意@Damien_The_Unbeliever。但是有时我在写单行或单词时更担心SQL –
它们是99.9999999%相同。只要你不做类似'WHERE column_value IN((从list_of_values中选择值,其中value ='All'limit 1))''那么你很好。 ()语句中的子查询带来了巨大的影响。 – MonkeyZeus