MYSQL ( field1, field2 ) = (x,y) vs field1= x AND field2 = Y 的区别

Posted

技术标签:

【中文标题】MYSQL ( field1, field2 ) = (x,y) vs field1= x AND field2 = Y 的区别【英文标题】:MYSQL Difference between ( field1, field2 ) = (x,y) vs field1= x AND field2 = Y 【发布时间】:2022-01-05 16:52:52 【问题描述】:

我有一个包含以下字段的表 studentDB

select sid, sname, sDOB from Student

我见过很多地方,(xx,yy)AND 有什么区别,哪个性能更好

select * from Student where (sid,sname) = (101,'foo')

select * from Student where sid = 101 AND sname = 'foo'

还有这个运算符 () 用于匹配时的名称是什么?

【问题讨论】:

没有区别。这只是语法糖。 【参考方案1】:

行构造函数比较在 SQL 语法中是合法的,但在 mysql 5.5 及更早的版本中,此语法不支持索引优化,因此不鼓励使用。

见https://dev.mysql.com/doc/refman/8.0/en/row-constructor-optimization.html

到目前为止,所有支持的 MySQL 版本都支持行构造函数比较的索引优化。缺少此功能的旧版本已经过时,因此无论如何您都不应该使用这些旧版本。因此,没有理由再避免使用这种语法了。

【讨论】:

【参考方案2】:

(sid,sname) 被称为“元组”,一些数据库引擎在不同程度上支持它们。 MySQL 8 做得很好。

现在,当使用相等时,这两个表达式之间没有区别。但是,元组对于不等式可能非常有用。例如:

select * from t where (a, b) <= (1, 0)

不同于:

select * from t where a <= 1 and b <= 0

当使用元组时,元素的比较是按顺序进行的,一个接一个。请参阅DB Fiddle 的差异示例。

【讨论】:

【参考方案3】:

2013-12-03 MySQL 5.7.3 变更日志:

优化器现在可以将范围扫描访问方法应用于 这种形式的查询:

SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' )); 以前,要使用范围扫描,必须使用 查询写成:

SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' ); 优化器使用范围扫描,查询 必须满足这些条件:

只能使用IN 谓词,不能使用NOT IN

IN 上的行构造函数中可能只有列引用 谓词的左侧。

IN 谓词的行构造函数必须不止一个 右手边。

IN 谓词右侧的行构造函数必须包含 只有运行时常量,它们可以是文字或本地列 在执行期间绑定到常量的引用。

适用查询的 EXPLAIN 输出将从全表或 索引扫描到范围扫描。通过检查也可以看到更改 的值 Handler_read_first, Handler_read_key, 和 Handler_read_next 状态变量。

(我不知道 MariaDB 是否进行了优化。)

【讨论】:

以上是关于MYSQL ( field1, field2 ) = (x,y) vs field1= x AND field2 = Y 的区别的主要内容,如果未能解决你的问题,请参考以下文章

按 Field1 Field2 Field3 ASC 和 DESC 对查询结果进行排序

mysql优化 - mysql 的 hint

Oracle 查询 where field1=field2 and field2=field1

枢轴计算公式:SUM(Field1)/AVG(Field2)

从存储在 MySQL 数据库中的 json 字符串中删除 key:value

MySQL防止重复插入相同记录