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

Som*_*luk 55 mysql sql postgresql in-operator equals-operator

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

第一个使用等式检查操作符

WHERE column_value = 'All'
Run Code Online (Sandbox Code Playgroud)

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

WHERE column_value IN ('All')
Run Code Online (Sandbox Code Playgroud)

请问SQL引擎更改IN=如果只有一个值吗?

在MySQL和PostgreSQL中有相同的差异吗?

sag*_*agi 58

有这两个语句之间没有区别,并且优化器将转换IN=时候IN有它只是一个元素.

虽然当你有这样的问题时,只需运行两个语句,运行它们的执行计划并查看差异.在这里 - 你找不到任何东西.

经过大量的在线搜索后,我发现了一个关于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  |
-----------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

并为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  |
-----------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

如您所见,两者都是相同的.这是在索引列上.对于未编制索引的列(仅全表扫描)也是如此.

  • @RahulTripathi我发现一般的SQL文档,我想它适用于所有DBMS. (7认同)
  • 我前一段时间看了这个,但无法对任何关于此的文件做好准备,很棒的答案! (4认同)
  • 该帖是不是来自于业绩的讨论.我认为它只是意味着在这两种说法的含义相同意义上的"等价物",而不是让有关优化任何声明.不过我认为,这必将进行优化,以相同. (4认同)

Rah*_*thi 8

使用单个值时没有区别.如果要检查上述两个查询的表扫描,索引扫描或索引搜索,您会发现两个查询之间没有区别.

在Mysql和PostgresSQL中有相同的不同之处吗?

不,它在两个引擎上没有任何区别(事实上,对于大多数数据库,包括SQL Server,Oracle等,它都是相同的).两个引擎都将转换IN=


小智 6

实际上没有太大差异,但如果您的column_value被索引,则IN运算符可能不会将其作为索引读取.

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


The*_*war 5

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

select * from emps where empid in (1)
select * from emps where empid=1
Run Code Online (Sandbox Code Playgroud)

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

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0)
Run Code Online (Sandbox Code Playgroud)

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

[PerformanceV3].[dbo].[Emps].[empID]=CONVERT_IMPLICIT(int,[@1],0)
Run Code Online (Sandbox Code Playgroud)

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


ale*_*xis 5

教一个人钓鱼等等.以下是如何自己查看查询的变体:

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关如何解释mysql EXPLAIN请求结果的信息.现在,请注意我们为两个查询获得了相同的输出:生成完全相同的"执行计划".该type行告诉我们查询使用非唯一索引(在这种情况下是外键),该ref行告诉我们通过将常量值与此索引进行比较来执行查询.