I have a table studentDB with below fields
select sid, sname, sDOB from Student
I have seen this is many place, what is difference between (xx,yy) vs AND, and which one is more performance wise better
select * from Student where (sid,sname) = (101,'foo')
vs
select * from Student where sid = 101 AND sname = 'foo'
And also what is name of this operator () when using for matching?
CodePudding user response:
(sid,sname)
is called a "tuple" and some database engines support them in varied degrees. MySQL 8 does it quite well.
Now, there's no difference between those two expressions when using equality. However, tuples can be quite useful for inequalities. For example:
select * from t where (a, b) <= (1, 0)
is different from:
select * from t where a <= 1 and b <= 0
When tuples are used the comparison of elements is done in sequence, one after the other. See example of differences at DB Fiddle.
CodePudding user response:
Row constructor comparison is legal in SQL syntax, but in versions of MySQL 5.5 and earlier, this syntax did not support index optimization, so it was not encouraged.
See https://dev.mysql.com/doc/refman/8.0/en/row-constructor-optimization.html
By now, all supported versions of MySQL do support index optimization for row constructor comparison. The older versions that lack this feature are past their end-of-life, so you shouldn't be using those old versions anyway. Therefore there's no reason to avoid this syntax anymore.
CodePudding user response:
2013-12-03 MySQL 5.7.3 changelog:
The optimizer now is able to apply the range scan access method to queries of this form:
SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));
Previously, for range scans to be used it was necessary for the query to be written as:
SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' );
For the optimizer to use a range scan, queries must satisfy these conditions:Only
IN
predicates can be used, notNOT IN
.There may only be column references in the row constructor on the IN predicate's left hand side.
There must be more than one row constructor on the IN predicate's right hand side.
Row constructors on the IN predicate's right hand side must contain only runtime constants, which are either literals or local column references that are bound to constants during execution.
EXPLAIN output for applicable queries will change from full table or index scan to range scan. Changes are also visible by checking the values of the Handler_read_first, Handler_read_key, and Handler_read_next status variables.
(I have no info on whether MariaDB has picked up the optimization.)