我有一个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'
当用于匹配时,这个运算符的名称是什么?
行构造函数比较在SQL语法中是合法的,但在MySQL 5.5及更早版本中,此语法不支持索引优化,因此不鼓励使用。
请参阅https://dev.mysql.com/doc/refman/8.0/en/row-constructor-optimization.html
到目前为止,所有支持的MySQL版本都支持行构造函数比较的索引优化。缺少此功能的旧版本已经过时,所以无论如何都不应该使用这些旧版本。因此,没有理由再回避这种语法了。
(sid,sname)
被称为";元组";一些数据库引擎在不同程度上支持它们。MySQL 8做得很好。
现在,当使用相等时,这两个表达式之间没有区别。然而,元组对于不等式是非常有用的。例如:
select * from t where (a, b) <= (1, 0)
不同于:
select * from t where a <= 1 and b <= 0
当使用元组时,元素的比较是按顺序进行的,一个接一个。请参阅DB Fiddle上的差异示例。
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,和句柄read_next状态变量。
(我没有关于MariaDB是否进行了优化的信息。(