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 对查询结果进行排序
Oracle 查询 where field1=field2 and field2=field1
枢轴计算公式:SUM(Field1)/AVG(Field2)