SQL Query: boolean processing - sql-server-2008

I have no idea if this is the right forum or not. Lets say I have the following:
SELECT *
FROM MyTable m
WHERE ((A OR B) AND (C OR D))
Assume that A, B, C, D are proper boolean clauses that each need to be evaluated on a row-level basis. Lets also assume no indexes.
This is logically equivalent to:
SELECT *
FROM MyTable m
WHERE (A AND C)
OR (A AND D)
OR (B AND C)
OR (B AND D)
Is there a performance advantage to either one? We're on MSSql-2008.

My understanding is that your first case is more efficient, because:
in this clause:
WHERE ((A OR B) AND (C OR D))
the entire statement fails if neither A or B are true; the Second part of the statement, (C OR D) is not evaluated. Even if A OR B are true, there is only one more pair to check - C OR D. Worst case is that four criteria are checked before the statement as a whole can be evaluated (if A = False, B = False, C= False, but D = True). Best case is, the statement becomes false after checking only A and B. If neither are true, then the entire statement is false.
In your second case, each of the four cases must ALL be evaluated before the statement as a whole can be evaluated.
Nesting the OR conditionals inside the AND means if the first case fails, more on along, nothing more of interest here. You improve things even more if you place the case most likely to be false as the first pair.
I will be interested to hear from others on this . . .

Related

Construct a function from the table with values and results

There are algorithms to convert truth table with multiple variable to a DNF (Disjunctive normal form). Is there a similar concept which can be generalized for variables taking a limited set of values?
For example, from this truth table we can compose DNF:
(¬A∧¬B∧¬D) ∨ (¬A∧B∧C) ∨ (A∧B∧D) ∨ (A∧¬B∧¬C)
Is there any automatic tools or algorithms which might help me to convert tables like this:
into the list of predicates composed of OR, AND, = ?
Result:
(a = A2) -> 1
((a = A3) AND (b = B2)) -> 1
otherwise -> 0
Each variable have a limited set of possible values. In my case I have 3 variable, each of them can take up to 30 different values.

MySQL Where 2 of x

How can i get only Lines, where 2 (or more) Where Clause of many are true?
For Example:
SELECT *
FROM A
WHERE CONVERT(AES_DECRYPT(name,'".$this->key."'),CHAR) LIKE '%".$this->escape($name)."%'"
OR CONVERT(AES_DECRYPT(name2,'".$this->key."'),CHAR) = '".$this->escape($name2)."'"
OR CONVERT(AES_DECRYPT(name3,'".$this->key."'),CHAR) = '".$this->escape($name3)."'"
OR CONVERT(AES_DECRYPT(name4,'".$this->key."'),CHAR) = '".$this->escape($name4)."'"
.....
is there a simply way to get only the results where 2 (or more) match, without creating a huge SQL Statement (each column with each other column - (name AND name2) OR (name AND name3) OR (name AND name4) OR ... )
In MySQL you can utilise the fact that it treats boolean expressions as 1 or 0 in a numeric context. Thus to check for 2 or more conditions being true, you can write
WHERE (condition 1) + (condition 2) + ... + (condition n) >= 2
Note that the parentheses around each condition are required to prevent any operator precedence issues.

SQL WHERE condition, why the result using 'a != 7 and b !=836' is not equal ' !(a=7 and b=836)'?

There are three records like:
a=7 , b=836
a=8 , b=836
a=7 , b=839
I want to get the result without (a=7 and b=836).
the result is empty when execute the sql like select * from test where a!=7 and b!=836,
but it got the correct result by using select * from test where a<>7 or b<>836.
I have two questions:
Why 'a!=7 and b!=836' not equal !(a=7 and b=836)?
What's the different between the two conditions ?
'a!=7 and b!=836' and 'a<>7 or b<>836'
The difference is in your logic operators, and and or, in combination with parentheses.
select * from test where a!=7 and b!=836
This query would select where BOTH of your statements return true, that is both a is not 7, and b is not 836. This would return nothing, there is no record where both of these are true.
select * from test where !(a=7 and b=836)
When you put the parentheses around your and, you move the logic around. That statement means that all records NOT matching any record where both a is 7 and b is 836. So inside the parenthesis it matches the first record, then it inverts that selection.
select * from test where a<>7 or b<>836
The <> is the same as != (Link to documentation). But in this query you use or. So it will match any record where a is not 7, AND any record that is not 836. So would match both second and third row.
For more reading material, take a look at the De Morgan's Laws. !(a and b) equals !a or !b. More explanation here and here.
Actually != and <> exactly the same. See the documentation.
<> is sql standard, != non-standard.
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_not-equal

Given 3 possible values for X, is it faster to do WHERE (X = B OR X = C), or to do WHERE X != A?

Given 3 possible values for X (A, B, C), is it faster to do:
WHERE (X = 'B' OR X = 'C'), or
WHERE X != 'A'
Or does it depend? If so, then what does it depend on?
Option 1:
WHERE (X = 'B' OR X = 'C')
and
WHERE X IN ('B', 'C')
are equivalent and may use an index on (X).
Option 2:
WHERE X != 'A'
will not use an index on (X). See a comment by Henrik Grubbström at the MySQL docs, How MySQL Optimizes WHERE Clauses page:
Indexes are ignored for the <> operator:
So, if the use of index makes the query faster (for example, if 99% of the table has X = 'A'), use the first option.
Note: The != operator is a synonym (in MySQL) of the SQL-standard <> inequality operator.
Your second operation should be faster because it requires one less logical check. If it's scanning a value, it only has to check to make sure it's not A, where your first operation would need to match B and then if there is no match, C. Regarding the use of an index, it depends on what your index looks like and how it's being called. If you have an index on columns W, X and you only filter X, the index will not be used as indexes work left-to-right.
Direct equality (=) and inquality (!=) takes the same time. Best case your queries will run the same time, but worst case, case 1. could be slower as you're adding another case to check by the OR.
Of course not knowing if there are indexes or the distribution of values for X can affect the performance...
In my opinion the second item is better because it is always only one comparison; in the first item if the value to be tested is 'C' or 'A' you have to 2 comparison, the fisrt (X = 'B') will fail and then the second comparison gives the final result.
If case 1 uses an index, which in my view it should if there is an index on X, it will be faster than case 2 if case 2 doesn't use an index, which in my view it won't. In general. It also depends on the actual distribution of values: if significantly skewed, results will vary accordingly.

Using <> in MySQL

I have come across <> used in a statement conditions a few times. Example:
SELECT param, d.param
FROM panel p join object d on p.id=d.id
WHERE param IS NOT NULL and param<>''
Let me confirm the statement above has not been tested, it mimics some of the statements that I have come across.
My question is, what is the meaning of the the diamond <> condition?
<> is like NOT .. = .. and !=. It means not equal.
MySQL comparison operators - not equal
its the opposite of "equal" so it is "not equal".
in C it is !=
so in your question it means param is not a empty string