The impact of the order of SQL conditions on performance

Reprinted: http://www.cnblogs.com/zyk/archive/2009/09/25/1573687.html

 

 People often ask whether the conditional writing order of the Where clause in oracle has an impact on SQL performance. My intuition is that it has no impact, because if this order has an impact, Oracle should have been able to do automatic optimization long ago, but there has been no information about this. solid evidence. The articles found on the Internet are generally considered to have no effect in the RBO optimizer mode (starting at 10G, the default is the RBO optimizer mode), but have an impact in the CBO optimizer mode, there are two main points of view:

a. The condition that can make the least result is placed on the far right, and the SQL execution is filtered from right to left in the result set;

b. Some experiments have shown that the condition that can make the least result is placed on the leftmost, and the SQL performance is higher.

       I have checked the online documents of oracle8 to 11G. Regarding the relevant chapters of SQL optimization, there is no document that says that the conditions in the where clause have an impact on SQL performance. Which point of view is correct? There is no exact conclusion, so I have to come by myself Do experimental proof. It turns out that the execution of SQL conditions is right-to-left, but the order of conditions has no effect on SQL performance .

 

Experiment 1: Prove that SQL parsing is right-to-left

       The following experiment can get the same result in both 9i and 10G: the first statement executes without error, the second statement will prompt that the divisor cannot be zero.

 

Select 'ok' From Dual Where 1 / 0 = 1 And 1 = 2;
Select 'ok' From Dual Where 1 = 2 And 1 / 0 = 1;

 

It proves that the parsing of SQL is right-to-left.

 

Experiment 2: Prove that the SQL condition is executed from right to left

 

drop table temp;

create table temp( t1 varchar2(10),t2 varchar2(10));

insert into temp values('zm','abcde');

insert into temp values('sz','1');

insert into temp values('sz','2');

commit;

 

select * from temp where to_number(t2)>1 and t1='sz';
select * from temp where t1='sz' and to_number(t2)>1;

Executed on 9i, the first statement will be executed without error, and the second statement will prompt "invalid number"

Executed on 10G, both statements work without errors.

Note: On 9i, the execution of SQL conditions is indeed from right to left, but what adjustment has been made on 10G?

 

Experiment 3: Prove that the execution of SQL conditions on 10g is right-to-left

 

Create Or Replace Function F1(v_In Varchar2) Return Varchar2 Is

Begin

 Dbms_Output.Put_Line('exec F1');

 Return v_In;

End F1;

/

Create Or Replace Function F2(v_In Varchar2) Return Varchar2 Is

Begin

 Dbms_Output.Put_Line('exec F2');

 Return v_In;

End F2;

/

SQL> set serverout on;

SQL> select 1 from dual where f1('1')='1' and f2('1')='1';

         1

----------

         1

exec F2

exec F1

SQL> select 1 from dual where f2('1')='1' and f1('1')='1';

         1

----------

         1

exec F1

exec F2

  

It turns out that the execution order of SQL conditions is right-to-left.

 

       Then, based on the analysis of this result, putting the condition with the least result on the far right, will it reduce the number of records used when other conditions are executed, thereby improving performance?

For example: in the following SQL conditions, should the order of the SQL conditions be adjusted?

 

Where A.结帐id Is Not Null

And A. Record Status <> 0

And A. Billing Fee = 1

And (Nvl(A.Accounted amount, 0)<>Nvl(A.Checkout amount, 0) Or Nvl(A.Checkout amount, 0)=0)

And A. Patient ID=[1] And Instr([2],','||Nvl(A. Home ID,0)||',')>0

And A. Registration Time Between [3] And [4]

And A. Clinic Logo <> 1

 

       In fact, from the analysis of the execution plan of this SQL statement, Oracle will first find out the conditions that use indexes or joins between tables to filter the data set, and then check whether the records involved in these result data blocks are checked one by one. All conditions are met, so the order of conditions has little effect on performance.

 

       Does the order of conditions have any performance impact if there are no indexes and joins between tables? Let's look at another experiment.

Experiment 4: It is proved that the order of conditions has no effect on performance.

 

SQL> select count(*) from diagnosis and treatment project directory where operation type='1';

 COUNT(*)

----------

      3251

SQL> select count(*) from diagnosis and treatment project directory where category='Z';

 COUNT(*)

----------

       170

SQL> select count(*) from diagnosis and treatment item directory where category='Z' and operation type='1';

 COUNT(*)

----------

         1

Declare

 V1 Varchar2(20);

Begin

 For I In 1 .. 1000 Loop   

   --Select Name Into V1 From Diagnosis and Treatment Item Directory Where Category = 'Z' And Operation Type = '1';

   select name Into V1 from diagnosis and treatment item directory where operation type='1' and category='Z';

 End Loop;

End;

 

The above SQL executes 1000 queries in two ways, and the results are as follows:

 

action type = '1' on the far right | category = 'Z' on the far right

0.093                            |      1.014

1.06                              |      0.999

0.998                            |      1.014

 

       It stands to reason that the order is executed from right to left. When "category='Z'" is on the far right, 170 records are obtained by filtering first, and then the ones that match "operation type='1'" are found. In comparison, "operation type='1'" When type = '1'" is on the far right, first filter to get 3251 records, and then find the records that match "category = 'Z'", the efficiency should be lower, but the actual result is that the total time of the two is about the same.

       In fact, from the analysis of Oracle's data access principle, the two sequential writing methods and execution plans are the same, both are full table scans, and all data blocks of the table must be accessed in turn, and for the rows in each data block, Check one by one if both conditions are met. Therefore, there is no problem of how many pieces of data are filtered out first.

       To sum up, the order of the conditions in the Where clause has no effect on performance (whether it is CBO or RBO optimizer mode). Note that, as an extra, here is only the order of the conditions, not the order of the tables. In RBO optimizer mode, the tables should be arranged from left to right in descending order of the number of result records, because when connecting between tables, the rightmost table will be placed at the outermost level of the nested loop. The lower the number of cycles in the outermost layer, the higher the efficiency.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326402022&siteId=291194637