0

我有一个包含以下字段的表 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'

并且在用于匹配时这个运算符()的名称是什么?

4

3 回答 3

0

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

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

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

不同于:

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

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

于 2021-11-28T15:07:27.173 回答
0

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

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

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

于 2021-11-28T15:48:53.863 回答
0

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_firstHandler_read_keyHandler_read_next 状态变量的值也可以看到更改 。

(我不知道 MariaDB 是否接受了优化。)

于 2021-11-28T16:40:31.683 回答