Is there a performance difference between `=` and `<=>`? - mysql

I've recently changed all my where conditions to use <=> instead of = because I need to check against nulls. Are there any performance concerns?

There is no real performance impact here is a test to verify for yourself
mysql> SELECT BENCHMARK(1000000, (SELECT SQL_NO_CACHE userId FROM Activity WHERE userId<=>42459204 LIMIT 1));
Make sure that you need to use <=>
NULL-safe equal. This operator
performs an equality comparison like
the = operator, but returns 1 rather
than NULL if both operands are NULL,
and 0 rather than NULL if one operand
is NULL.
If you just need to check the rvalue do
col=CONST AND CONST IS NOT NULL
or t1.col=t2.col

<=> is basically a shortcut to include OR (Val1 IS NULL AND Val2 IS NULL) or IS NOT DISTINCT FROM
It is an additional operation but the difference should be negligible unless you are SELECTing the data to be compared because otherwise the first SELECT returning NULL doesn't need to execute the second SELECT because the standard equality operator = will always yield false.
As #Dathan noted, make sure this is actually when you intend to do.

Related

Has null instead of integer/string in the mysql WHERE clause any impact on the performance?

for a following query :
SELECT some_value
FROM some_table
WHERE param_one='62627'
AND param_two='1'
AND param_three=QUESTIONABLE_VALUE
Does it have any impact on the performance if QUESTIONABLE_VALUE is a null or an integer/string?
IS NULL Optimization. MySQL can perform the same optimization on col_name IS NULL that it can use for col_name = constant_value. For example, MySQL can use indexes and ranges to search for NULL with IS NULL.
You must have a composite index
`idx` (`param_one`,`param_two`,`param_three`)
Use EXPLAIN to check how the optimizer behave on different datatypes
If you have a parameter that may be null or may be non-null, and you want to match data that is the same, you would use the <=> operator (null-safe comparison).
SELECT some_value
FROM some_table
WHERE param_one='62627'
AND param_two='1'
AND param_three <=> QUESTIONABLE_VALUE
With =, the result will be null if either operand is null.
Your Title, plus the two answers so far, point out issues with testing against NULL. I want to point out an issue with "integer/string".
AND param_three = 123
can use an index if param_three is some numeric type, but not if it a VARCHAR. The column needs to be converted to numeric to perform the test.
The other way works fine -- these work equally well if param_two is numeric because the string literal is converted to numeric.
AND param_two='1'
AND param_two=1

MySQL - if condition optimization

Just wondering, how this query will be handled by MySQL, will sum() calculated twice if sum(credits) != NULL or does MySQL has optimization in place for such queries.
select if(sum(credits)=NULL, 0, sum(credits)) from ......
Thanks
If won't work. The first condition is always false. The correct way to compare to NULL is IS NULL, not =.
Just use this construct:
select coalesce(sum(credits), 0)
Using IF
SELECT IF(sum(credits) IS NULL, 0 ,sum(credits)) .....
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2; otherwise it returns expr3. IF() returns a numeric or string value, depending on the context in which it is used
Using IFNULL
SELECT IFNULL(sum(credits), 0) .....
Using COALESCE
SELECT COALESCE(sum(credits), 0) .....
Refer : MySQL Control Flow Functions
This is something we shouldn't worry about. With SQL we tell the DBMS what to do, not how to do it.
It is very, very likely that the DBMS will compute sum(credits) only once. It would seem rather stupid if not. However, this is not dictated by the SQL standard, so the DBMS programmers are free to choose how to code this. They could write the DBMS such that sum(credits) is computed twice. We cannot know whether they did or not, but as mentioned it is not likely and we shouldn't worry about it either.

In MySQL, which is more efficient: IFNULL or NULLIF?

These two MySQL functions do the same thing:
IFNULL(column_name, 'test') = 'test'
or
NULLIF(column_name, 'test') IS NULL
Which one is more efficient?
Purpose of NULLIF and IFNULL is not same, so performance comparison does not make any sense.
NULLIF is used to return null if the expression has a specific value, whereas IFNULL is used to return text if expression is null.
Example:
SELECT IFNULL(field,'empty') from table1;
Since null does not make much sense to end user.
insert into table1 (field) values (nullif(field,'empty'));
Since null has a special meaning in database.
They are both as efficient as each other - the functions have about the same overhead as each other.
But this is more efficient than either:
(column_name is null
or column_name = 'test')
Because the function doesn't need to be invoked.
You may find putting the more commonly encountered test first improves performance.
With questions like this, the simplest and more reliable way to discover relative performance is to just try them and compare query timings. Make sure you have production-sized and realistic-valued datasets so the test is fair.
they are used for different purpose, performance comparison doesn't make any sense.
select if(a,b,c); # a ? b : c # if a!=0 and a is not null then b else c
select ifnull(a,b); # a ? a : b # if a is not null then a else b
select nullif(a,b); # a=b ? null : a # if a=b then null else a
http://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html

MySQL comparison with null value

I have a column called CODE in a MySQL table which can be NULL. Say I have some rows with CODE='C' which I want to ignore in my select result set. I can have either CODE=NULL or CODE!='C' in my result set.
The following query does not return a row with CODE as NULL:
SELECT * from TABLE where CODE!='C'
But this query works as expected and I know it is the right way to do it.
SELECT * from TABLE where CODE IS NULL OR CODE!='C'
My question is why does having only CODE!='C' does not return rows where CODE=NULL? Definitely 'C' is not NULL. We are comparing no value to a character here. Can someone throw some light as why it doesn't work that way?
In MySQL, NULL is considered as a 'missing, unknown value', as opposed to no value. Take a look at this MySQL Reference on NULL.
Any arithmetic comparison with NULL does not return true or false, but returns NULL instead., So, NULL != 'C' returns NULL, as opposed to returning true.
Any arithmetic comparison with 'NULL' will return false. To check this in SQL:
SELECT IF(NULL=123,'true','false')
To check NULL values we need to use IS NULL & IS NOT NULL operator.
Based on my tests and the documentation here: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html
You can compare null and get a boolean result using <=>
NOTE: it looks like NOT EQ operator, but it's EQ operator
For example:
select x <=> y;
or
select #x <=> #y;
This also compares string vs null, string vs string, etc.
In SQL, the NULL value is a special value, not comparable with any other one.
The result of a direct comparison with a NULL is always NULL, although (unfortunately) you may find FALSE in some implementation.
To test a null value you should use IS NULL and IS NOT NULL.
SELECT *
FROM `table_name`
WHERE IFNULL(`column_name` != 'C', TRUE)
The specified problem can also appear in joins and the above answers aren't particularly helpful. The way I prefer to do it is by coalescing to otherwise impossible value. For example, this
select foo from bar
inner join baz on bar.x = baz.y
won't work if bar.x and baz.y are both nulls (join won't bring results). The workaround is to use e.g.
select foo from bar
inner join baz on coalesce(bar.x, -1) = coalesce(baz.y, -1)
where -1 is "impossible" value meaning it can never appear in the data set.
select * from user where application_id='1223333344' and name is null;
I use:
SELECT * from TABLE where NOT(CODE <=> 'C')

MySQL: selecting rows where a column is null

I'm having a problem where when I try to select the rows that have a NULL for a certain column, it returns an empty set. However, when I look at the table in phpMyAdmin, it says null for most of the rows.
My query looks something like this:
SELECT pid FROM planets WHERE userid = NULL
Empty set every time.
A lot of places said to make sure it's not stored as "NULL" or "null" instead of an actual value, and one said to try looking for just a space (userid = ' ') but none of these have worked. There was a suggestion to not use MyISAM and use innoDB because MyISAM has trouble storing null. I switched the table to innoDB but now I feel like the problem may be that it still isn't actually null because of the way it might convert it. I'd like to do this without having to recreate the table as innoDB or anything else, but if I have to, I can certainly try that.
SQL NULL's special, and you have to do WHERE field IS NULL, as NULL cannot be equal to anything,
including itself (ie: NULL = NULL is always false).
See Rule 3 https://en.wikipedia.org/wiki/Codd%27s_12_rules
SELECT pid FROM planets WHERE userid IS NULL
As all are given answers I want to add little more. I had also faced the same issue.
Why did your query fail? You have,
SELECT pid FROM planets WHERE userid = NULL;
This will not give you the expected result, because from mysql doc
In SQL, the NULL value is never true in comparison to any other value, even NULL. An expression that contains NULL always produces a NULL value unless otherwise indicated in the documentation for the operators and functions involved in the expression.
Emphasis mine.
To search for column values that are NULL, you cannot use an expr = NULL test. The following statement returns no rows, because expr = NULL is never true for any expression
Solution
SELECT pid FROM planets WHERE userid IS NULL;
To test for NULL, use the IS NULL and IS NOT NULL operators.
operator IS NULL tests whether a value is NULL.
operator IS NOT NULL tests whether a value is not NULL.
MySQL comparison operators
There's also a <=> operator:
SELECT pid FROM planets WHERE userid <=> NULL
Would work. The nice thing is that <=> can also be used with non-NULL values:
SELECT NULL <=> NULL yields 1.
SELECT 42 <=> 42 yields 1 as well.
See here: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to
Info from http://w3schools.com/sql/sql_null_values.asp:
1) NULL values represent missing unknown data.
2) By default, a table column can hold NULL values.
3) NULL values are treated differently from other values
4) It is not possible to compare NULL and 0; they are not equivalent.
5) It is not possible to test for NULL values with comparison
operators, such as =, <, or <>.
6) We will have to use the IS NULL and IS NOT NULL operators instead
So in case of your problem:
SELECT pid FROM planets WHERE userid IS NULL
Had the same issue where query:
SELECT * FROM 'column' WHERE 'column' IS NULL;
returned no values.
Seems to be an issue with MyISAM and the same query on the data in InnoDB returned expected results.
Went with:
SELECT * FROM 'column' WHERE 'column' = ' ';
Returned all expected results.
SELECT pid FROM planets WHERE userid is null;
I had the same issue when converting databases from Access to MySQL (using vb.net to communicate with the database).
I needed to assess if a field (field type varchar(1)) was null.
This statement worked for my scenario:
SELECT * FROM [table name] WHERE [field name] = ''