|
tm
Posting Yak Master
160 Posts |
Posted - 2007-10-25 : 10:24:14
|
| I am wondering if anyone can enlighten me or comment on when to use OVER() function instead of sub queryUsing OVER() is much more readable and much easier to write but have found it is taking much much longer.Using OVER() function took 4 minute and 30 seconds to run compared with 2 seconds with sub query (please see below example and some details)-- =======declare @a table (Customer_ID bigint, Batch_ID bigint, [File_ID] bigint, Code_ID bigint)declare @b table (Batch_ID bigint, [File_ID] bigint)declare @c table ([File_ID] bigint, FileSource varchar(5))declare @d table (Customer_ID bigint, supptype smallint, EffectiveDate datetime, ProdOpt varchar(50))-- Actual rows in table 20625 instead of 4insert into @aselect 1,1,1, 1union allselect 2,1,1,2union allselect 2,1,1,3union allselect 3,1,1,3-- Actual rows in table = 86 instead of 1insert into @bselect 1,1-- Actual rows in table = 12 instead of 1insert into @cselect 1, 'files'-- Actual rows in table = 2338 instead of 7insert into @dselect 1, 1, getdate(), 'aa'union allselect 1,2, getdate(), 'aa'union allselect 1,3, getdate(), 'aa'union allselect 1,5, getdate(), 'aa'union allselect 2,3, getdate(), 'aa'union allselect 3,5, getdate(), 'bb'union allselect 3,6, getdate(), 'bb'-- With actual tables with additional columns-- Time to complete : 4 minutes 30 secondsSELECT CUST.Customer_ID, Code_ID , prodopt,SUPP.EffectiveDate,FileSourceFROM@a CUST INNER JOIN @b BATCHF ON CUST.Batch_ID = BATCHF.Batch_IDINNER JOIN @c FILET ON BATCHF.[File_ID] = FILET.[File_ID]INNER JOIN (SELECT Customer_ID, EffectiveDate, ProdOpt, supptype FROM @d WHERE supptype = 1 UNION ALL SELECT DISTINCT Customer_ID, EffectiveDate, ProdOpt, MIN(supptype) OVER(PARTITION BY Customer_ID) AS supptype FROM @d WHERE supptype BETWEEN 2 AND 4 UNION ALL SELECT DISTINCT Customer_ID, EffectiveDate, ProdOpt, MIN(supptype) OVER(PARTITION BY Customer_ID) AS supptype FROM @d WHERE supptype > 4 ) SUPP ON CUST.Customer_ID = SUPP.Customer_ID-- With actual tables with additional columns-- Time to complete : 2 secondsSELECT CUST.Customer_ID, Code_ID , prodopt,SUPP.EffectiveDate,FileSourceFROM@a CUST INNER JOIN @b BATCHF ON CUST.Batch_ID = BATCHF.Batch_IDINNER JOIN @c FILET ON BATCHF.[File_ID] = FILET.[File_ID]INNER JOIN (SELECT Customer_ID, EffectiveDate, ProdOpt, supptypeFROM @dWHERE RTRIM(CAST(Customer_ID AS VARCHAR)) + CAST(supptype AS CHAR(1)) in(SELECT RTRIM(CAST(Customer_ID AS VARCHAR)) + CAST(supptype AS CHAR(1)) FROM @d WHERE supptype = 1 UNION ALL SELECT RTRIM(CAST(Customer_ID AS VARCHAR)) + CAST(MIN(supptype) AS CHAR(1)) FROM @d WHERE supptype BETWEEN 2 AND 4 GROUP BY Customer_ID UNION ALL SELECT RTRIM(CAST(Customer_ID AS VARCHAR)) + CAST(MIN(supptype) AS CHAR(1)) FROM @d WHERE supptype > 4 GROUP BY Customer_ID ) ) SUPP ON CUST.Customer_ID = SUPP.Customer_ID-- The difference in time is due to using OVER()-- If this query runs on it's own it takes less than one secondSELECT Customer_ID, EffectiveDate, ProdOpt, supptype FROM @d WHERE supptype = 1 UNION ALL SELECT DISTINCT Customer_ID, EffectiveDate, ProdOpt, MIN(supptype) OVER(PARTITION BY Customer_ID) AS supptype FROM @d WHERE supptype BETWEEN 2 AND 4 UNION ALL SELECT DISTINCT Customer_ID, EffectiveDate, ProdOpt, MIN(supptype) OVER(PARTITION BY Customer_ID) AS supptype FROM @d WHERE supptype > 4 |
|