SQL WHERE 절이 단락 되었습니까?
SQL WHERE 절의 부울 표현식 이 단락 평가 됩니까?
예를 들면 다음과 같습니다.
SELECT *
FROM Table t
WHERE @key IS NULL OR (@key IS NOT NULL AND @key = t.Key)
@key IS NULL 이 true로 평가 되면 @key IS NOT NULL AND @key = t. 키가 평가됩니까?
아니라면 왜 안됩니까?
그렇다면, 보장됩니까? ANSI SQL의 일부입니까, 아니면 데이터베이스 특정입니까?
데이터베이스에 특정한 경우 SqlServer? 신탁? MySQL?
ANSI SQL Draft 2003 5WD-01- 프레임 워크 -2003-09.pdf
6.3.3.3 규칙 평가 순서
[...]
우선 순위가 형식이나 괄호로 결정되지 않는 경우, 효과적인 표현 평가는 일반적으로 왼쪽에서 오른쪽으로 수행됩니다. 그러나 표현식이 실제로 왼쪽에서 오른쪽으로 평가되는지, 특히 피연산자 나 연산자가 조건을 발생시킬 수 있거나 표현식의 모든 부분을 완전히 평가하지 않고 표현식의 결과를 결정할 수있는 경우 구현에 따라 다릅니다 .
위의 단락은 실제로 사용할 수 없습니다.
필요한 경우 Case 문을 제안합니다.
Where Case when Expr1 then Expr2 else Expr3 end = desiredResult
Expr1
항상 평가하지만 중 하나입니다 Expr2
및 Expr3
행마다 평가됩니다.
나는 이것이 세 가지 이유로 단락되지 않은 것처럼 작성하는 경우 중 하나라고 생각합니다.
MSSQL의 경우 명확한 위치에서 BOL을 살펴 보아도 해결되지 않으므로 정식으로 모호합니다.
적어도 내 코드가 작동한다는 것을 알고 있기 때문입니다. 그리고 더 중요한 것은, 나를 따르는 사람들도 마찬가지입니다. 그래서 나는 계속해서 같은 질문을 통해 걱정하도록 그들을 설정하지 않습니다.
여러 DBMS 제품에 대해 자주 글을 쓰며 쉽게 해결할 수 있다면 차이점을 기억하고 싶지 않습니다.
SQL Server (2005)의 단락이 보장되는 것은 아닙니다. SQL Server는 효과적인 실행 계획을 세우기 위해 많은 것들 (인덱스, 통계, 테이블 크기, 리소스 등)을 고려한 최적화 알고리즘을 통해 쿼리를 실행합니다. 이 평가 후에는 단락 논리가 보장된다고 확신 할 수 없습니다.
나는 얼마 전에 같은 질문을 겪었고 나의 연구는 실제로 나에게 확실한 대답을주지 못했다. 작은 쿼리를 작성하면 작동한다는 증거를 얻을 수 있지만 데이터베이스의로드가 증가함에 따라 테이블이 커지고 데이터베이스에서 상황이 최적화되고 변경된다는 결론을 얻을 수 있습니다. 보류. 나는주의를 기울일 수 없었고 단락을 보장하기 위해 WHERE 절에서 CASE를 사용했습니다.
데이터베이스 작동 방식을 명심해야합니다. 매개 변수화 된 쿼리가 주어지면 db는 매개 변수 값없이 해당 쿼리를 기반으로 실행 계획을 작성합니다. 이 쿼리는 실제 제공된 값에 관계없이 쿼리가 실행될 때마다 사용됩니다. 쿼리가 특정 값으로 단락되는지 여부는 실행 계획에 중요하지 않습니다.
나는 일반적으로 이것을 선택적 매개 변수에 사용합니다. 단락과 동일합니까?
SELECT [blah]
FROM Emp
WHERE ((@EmpID = -1) OR (@EmpID = EmpID))
이것은 나에게 -1을 전달하거나 옵션의 속성 검사를 설명 할 수있는 옵션을 제공합니다. 때로는 여러 테이블 또는 바람직하게보기를 조인하는 것이 포함됩니다.
DB 엔진에 제공하는 추가 작업을 완전히 확신하지 못하는 매우 편리합니다.
SQL Server의 경우 버전에 따라 다르다고 생각하지만 SQL Server 2000에 대한 나의 경험은 @key가 null 인 경우에도 여전히 @key = t를 평가한다는 것입니다. 즉, WHERE 절을 평가할 때 효율적인 단락을 수행하지 않습니다.
사용자가 다양한 기준을 입력하거나 입력 할 수없는 유연한 쿼리를 수행하는 방법으로 예제와 같은 구조를 추천하는 사람들을 보았습니다. 내 관찰은 @key가 null 일 때 Key가 쿼리 계획에 여전히 관여하고 Key가 색인화되면 색인을 효율적으로 사용하지 않는다는 것입니다.
다양한 기준을 가진 이러한 종류의 유연한 쿼리는 동적으로 생성 된 SQL이 실제로 가장 좋은 방법 일 수 있습니다. @key가 null이면 쿼리에 전혀 포함시키지 않습니다.
나는 짧은 순환에 대해 모른다.하지만 if-else 문으로 쓰겠 다.
if (@key is null)
begin
SELECT *
FROM Table t
end
else
begin
SELECT *
FROM Table t
WHERE t.Key=@key
end
또한 변수는 항상 방정식의 오른쪽에 있어야합니다. 이것은 처칠 수 있습니다.
http://en.wikipedia.org/wiki/Sargable
Just stumbled over this question, and had already found this blog-entry: http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/
The SQL server is free to optimize a query anywhere she sees fit, so in the example given in the blog post, you cannot rely on short-circuiting.
However, a CASE is apparently documented to evaluate in the written order - check the comments of that blog post.
Main characteristic of short circuit evaluation is that it stops evaluating the expression as soon as the result can be determined. That means that rest of expression can be ignored because result will be same regardless it is evaluated or not.
Binary boolean operators are comutative, meaning:
a AND b == b AND a
a OR b == b OR a
a XOR b == b XOR a
so there is no guarantee on order of evaluation. Order of evaluation will be determined by query optimizer.
In languages with objects there can be situations where you can write boolean expressions that can be evaluated only with short circuit evaluation. Your sample code construction is often used in such languages (C#, Delphi, VB). For example:
if(someString == null | someString.Length == 0 )
printf("no text in someString");
This C# example will cause exception if someString == null
because it will be fully evaluated. In short circuit evaluation, it will work every time.
SQL operates only on scalar variables (no objects) that cannot be uninitialized, so there is no way to write boolean expression that cannot be evaluated. If you have some NULL value, any comparison will return false.
That means that in SQL you cannot write expression that is differently evaluated depending on using short circuit or full evaluation.
If SQL implementation uses short circuit evaluation, it can only hopefully speed up query execution.
Below a quick and dirty test on SQL Server 2008 R2:
SELECT *
FROM table
WHERE 1=0
AND (function call to complex operation)
This returns immediately with no records. Kind of short circuit behavior was present.
Then tried this:
SELECT *
FROM table
WHERE (a field from table) < 0
AND (function call to complex operation)
knowing no record would satisfy this condition:
(a field from table) < 0
This took several seconds, indicating the short circuit behavior was not there any more and the complex operation was being evaluated for every record.
Hope this helps guys.
Here is a demo to prove that MySQL does perform WHERE clause short-circuiting:
This runs the following queries:
SELECT myint FROM mytable WHERE myint >= 3 OR myslowfunction('query #1', myint) = 1;
SELECT myint FROM mytable WHERE myslowfunction('query #2', myint) = 1 OR myint >= 3;
The only difference between these is the order of operands in the OR condition.
myslowfunction
deliberately sleeps for a second and has the side effect of adding an entry to a log table each time it is run. Here are the results of what is logged when running the above two queries:
myslowfunction called for query #1 with value 1
myslowfunction called for query #1 with value 2
myslowfunction called for query #2 with value 1
myslowfunction called for query #2 with value 2
myslowfunction called for query #2 with value 3
myslowfunction called for query #2 with value 4
The above shows that a slow function is executed more times when it appears on the left side of an OR condition when the other operand isn't always true (due to short-circuiting).
This takes an extra 4 seconds in query analyzer, so from what I can see IF is not even shorted...
SET @ADate = NULL
IF (@ADate IS NOT NULL)
BEGIN
INSERT INTO #ABla VALUES (1)
(SELECT bla from a huge view)
END
It would be nice to have a guaranteed way!
It is but obvious that MS Sql server supports Short circuit theory, to improve the performance by avoiding unnecessary checking,
Supporting Example:
SELECT 'TEST'
WHERE 1 = 'A'
SELECT 'TEST'
WHERE 1 = 1 OR 1 = 'A'
Here, the first example would result into error 'Conversion failed when converting the varchar value 'A' to data type int.'
While the second runs easily as the condition 1 = 1 evaluated to TRUE and thus the second condition doesn't ran at all.
Further more
SELECT 'TEST'
WHERE 1 = 0 OR 1 = 'A'
here the first condition would evaluate to false and hence the DBMS would go for the second condition and again you will get the error of conversion as in above example.
NOTE: I WROTE THE ERRONEOUS CONDITION JUST TO REALIZE WEATHER THE CONDITION IS EXECUTED OR SHORT-CIRCUITED IF QUERY RESULTS IN ERROR MEANS THE CONDITION EXECUTED, SHORT-CIRCUITED OTHERWISE.
SIMPLE EXPLANATION
Consider,
WHERE 1 = 1 OR 2 = 2
as the first condition is getting evaluated to TRUE, its meaningless to evaluate the second condition because its evaluation in whatever value would not affect the result at all, so its good opportunity for Sql Server to save Query Execution time by skipping unnecessary condition checking or evaluation.
in case of "OR" if first condition is evaluated to TRUE the entire chain connected by "OR" would considered as evaluated to true without evaluating others.
condition1 OR condition2 OR ..... OR conditionN
if the condition1 is evaluated to true, rest all of the conditions till conditionN would be skipped. In generalized words at determination of first TRUE, all other conditions linked by OR would be skipped.
Consider the second condition
WHERE 1 = 0 AND 1 = 1
as the first condition is getting evalutated to FALSE its meaningless to evaluate the second condition because its evaluation in whatever value would not affect the result at all, so again its good opportunity for Sql Server to save Query Execution time by skipping unnecessary condition checking or evaluation.
in case of "AND" if first condition is evaluated to FALSE the entire chain connected with the "AND" would considered as evaluated to FALSE without evaluating others.
condition1 AND condition2 AND ..... conditionN
if the condition1 is evaluated to FALSE, rest all of the conditions till conditionN would be skipped. In generalized words at determination of first FALSE, all other conditions linked by AND would be skipped.
THEREFOR, A WISE PROGRAMMER SHOULD ALWAYS PROGRAM THE CHAIN OF CONDITIONS IN SUCH A WAY THAT, LESS EXPENSIVE OR MOST ELIMINATING CONDITION GETS EVALUATED FIRST, OR ARRANGE THE CONDITION IN SUCH A WAY THAT CAN TAKE MAXIMUM BENEFIT OF SHORT CIRCUIT
참고URL : https://stackoverflow.com/questions/789231/is-the-sql-where-clause-short-circuit-evaluated
'IT' 카테고리의 다른 글
iOS5 SDK의 자동 참조 계산에 대한 몇 가지 질문 (0) | 2020.06.27 |
---|---|
다이나믹하고 개인화 된 웹 애플리케이션에 적합한 응답 시간은 무엇입니까? (0) | 2020.06.27 |
PHP에서 주석을 달기 위해 해시 기호 (#)를 사용할 수 있습니까? (0) | 2020.06.27 |
PHP에서 ereg 표현식을 preg로 변환하려면 어떻게해야합니까? (0) | 2020.06.27 |
자바`최종`방법 : 그것은 무엇을 약속합니까? (0) | 2020.06.27 |