473,504 Members | 13,746 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to speed up query that returns nulls and dates within a range

46 New Member
Okay here is another piece of query optimization for you guys. I have this stored procedure as you know which joins many tables. It's purpose is to be a search for an online application. So they go to the page and they have 2 fields for Age. They want all data between 0 and 10 days old. The table that joins for age has to be a left join because there are sometimes no records but we want to include all records from the base table. So I need to figure out the aged dates like Getdate() & Getdate() - 10. Then I have to say give me all the records that between 0 & 10. That works fine, but if you don't enter an Age you should get all records including those with a Null in the date column. So I have to set a range and then say, "OR IS NULL". Or I have to use a function in the where clause to replace the null - no!!, or I should be able to use a case statement. I am not sure what the best way is to handle this. If I use a case statement it runs in 8 seconds but it does not include the Nulls. If I use an "OR". It more than doubles the run time.

Please see my example.
Expand|Select|Wrap|Line Numbers
  1. Create Table DateTest1
  2. (ID int,
  3. name varchar(10),
  4. datetest datetime
  5. )
  6.  
  7. Create Table DateTest2
  8. (
  9. ID int,
  10. Descripttion varchar(35)
  11. )
  12.  
  13. Insert into DateTest1  Values (1,'Joe',Getdate() -1) , (2,'Jim',NULL), (3,'Jake',Getdate() -7), (4,'John',NULL), (5,'Jan',Getdate() -10), (6,'Juno',Getdate() -5)
  14.  
  15. Insert into DateTest2  Values (1,'Descr 1') , (2,'Descr 2'), (3,'Descr 3'), (4,'Descr 4'), (5,'Descr 5'), (6,'Descr 6')
  16.  
  17. Select a.id, a.name, a.datetest, b.descripttion from DateTest2 b
  18. Inner Join DateTest1 a on a.id = b.id
  19. where a.datetest  between GETDATE()- 11 and GETDATE() or 
  20.                          a.datetest is null 
  21.  
  22. --Case statement does not include the Nulls
  23. --where a.datetest = case  When a.datetest is null then a.datetest
  24. --                         When a.datetest  between GETDATE()- 11 and 
  25. --                         GETDATE() then a.datetest end
  26.  
  27. --Or I can use something like this.
  28. --a.datetest >= GETDATE()- 11 and a.datetest <= GETDATE() or 
  29. --a.datetest is null
Well you get the idea. Should I make another thread?
Mar 16 '12 #1
12 1833
Rabbit
12,516 Recognized Expert Moderator MVP
Since this is about a specific query, I've moved it to its own thread.

You can use the the ISNULL() function to change the null values to GETDATE(). If that's too slow because it operates on one of the fields, then try a union all approach.

On a side note, the case statement doesn't do what you think it does. A null does not = null. For null comparions, you have to use IS NULL. You can't use NULL = NULL.
Mar 16 '12 #2
Vikki McCormick
46 New Member
Thanks. That doesn't work. I am not sure what's going here. Does CASE exclude nulls in the same way that an IN statement would?

I feel I am not understanding how this is working internally.

Okay I am totally struggling with being positive with this thing. It's because I have to use the isNull on the left side of the predicate, but is that a performance disaster?
Mar 16 '12 #3
Rabbit
12,516 Recognized Expert Moderator MVP
It's not the CASE statement that's excluding NULLs. It's being excluded because of how you're trying to compare them. You misunderstand what NULL means. NULL doesn't mean that there's an absence of a value. A NULL can be anything. It is unlikely for two NULLs to be equal.
NULL = NULL will always return FALSE. This is not a true statement. Your CASE statement is basically doing that comparison on NULLs.

I wouldn't call it a disaster per se. But performance will definitely suffer because of the calculation that needs to be done. Did you try the UNION ALL method? You didn't say whether or not you did.
Mar 16 '12 #4
ck9663
2,878 Recognized Expert Specialist
When you say a user input is optional, that means there's a variable involve. You cannot hard code the getdate() function because it will always calculate the age based on today's date. What if the date that your user want is yesterday? Also, is your date column time sensitive? You also need to consider that.

Just modify your code to check the variable, not the column. If the variable is NULL return everything.

Something like...

Expand|Select|Wrap|Line Numbers
  1. declare @DateVar datetime
  2.  
  3. --set @DateVar = getdate()
  4.  
  5. Select a.id, a.name, a.datetest, b.descripttion,
  6.    DateFrom = dateadd(dd, -10, DATEADD(dd,DATEDIFF(dd,0,@DateVar),0)),
  7.    DateTo = dateadd(ms,-2,DATEADD(dd,DATEDIFF(dd,0,DATEADD(d,+1,@DateVar)),0)) 
  8. from #DateTest2 b
  9. left Join #DateTest1 a on a.id = b.id
  10. where (a.datetest  between dateadd(dd, -10, DATEADD(dd,DATEDIFF(dd,0,@DateVar),0)) and
  11.                           dateadd(ms,-2,DATEADD(dd,DATEDIFF(dd,0,DATEADD(d,+1,@DateVar)),0)))
  12.       or @DateVar is null
  13.  
  14.  
Just comment out the set if you need to test it for specific date.

Happy Coding!!!


~~ CK
Mar 16 '12 #5
Vikki McCormick
46 New Member
Ugh.. this works. I lost 6 seconds... grr.. still 20 seconds is better than 13 minutes.

Expand|Select|Wrap|Line Numbers
  1. isNull(Requests.ProcessingComplete,'01/01/1900') = case when Requests.ProcessingComplete is Null then '01/01/1900'
  2.                                             when Requests.ProcessingComplete between @AgeFromDate and  @AgeToDate then Requests.ProcessingComplete
  3.                                             end
Yes ck9663 it's a variable. I didn't want to post the whole thing, because it's supposed to be proprietary, and because it's huge and to explain all that is going on would take a long time. The sproc basically is a catch all query that allows the user to go to a form and add in different variables to search a ton of information. It has to allow for the value or the null. I need to get all possible rows if there are all nulls being passed from the form.

Thanks for the Happy Coding reminder. :)
Mar 16 '12 #6
Rabbit
12,516 Recognized Expert Moderator MVP
This will probably be faster.
Expand|Select|Wrap|Line Numbers
  1. ISNULL(Requests.ProcessingComplete, @AgeFromDate) BETWEEN @AgeFromDate AND @AgeToDate
I still think the UNION ALL could be faster. You should try that as well.
Mar 16 '12 #7
Vikki McCormick
46 New Member
I found this example. Does isNull replace the COELESCE function?

Expand|Select|Wrap|Line Numbers
  1. SELECT * 
  2. FROM MyTable 
  3. WHERE  
  4.      MyTable.StartDate >= COALESCE(MyTable.StartDate, "1/1/1900")  
  5.      /* Date selected as earliest plausible constant to avoid min() lookup */ 
  6.  
  7.  AND MyTable.EndDate <= COALESCE(MyTable.EndDate, "1/1/3001") 
  8.      /* Date selected as latest plausible constant to avoid max() lookup */ 
  9.  
Rabbit,

I tried UNION ALL yesterday, and I am getting the same time frame as using the isNull on the left predicate.

There are 4 Left Joined tables. Unavoidable if the form is going to work. I wonder if possibly there is a better way to design this type of process. Are there standard good practice designs for online catch all queries?
Mar 16 '12 #8
Rabbit
12,516 Recognized Expert Moderator MVP
COALESCE is slightly different but very similar to ISNULL. ISNULL is probably a little faster. But you can do the same thing with either function.
Mar 16 '12 #9
Rabbit
12,516 Recognized Expert Moderator MVP
As long as you need all the records from the base table and some of those fields on the joined tables, I'm afraid there's no way around it. The only thing left to do at this point is to reevaluate what you're showing the user and see whether or not they actually need all those tables.

I'm assuming you have an index (collated if you don't have one already) on at least the date field?
Mar 16 '12 #10
Vikki McCormick
46 New Member
Yes. I indexed. I will reveiw them again though to make absolutely sure I didn't put the order in wrong or something.
Mar 16 '12 #11
Vikki McCormick
46 New Member
Rabbit using

Expand|Select|Wrap|Line Numbers
  1. 1.ISNULL(Requests.ProcessingComplete, @AgeFromDate) BETWEEN @AgeFromDate AND @AgeToDate
  2.  
I gained one second. Huzzah!
Mar 16 '12 #12
Rabbit
12,516 Recognized Expert Moderator MVP
I think at this point it's about as optimized as you can get it.

You can try adding the WHERE and JOIN fields into the same index as your date field and see if that gains you anything. And also, create indexes on the other tables on the JOIN fields. And if that nets you some speed, try adding in any ORDER BY fields. And if that works, start adding in the SELECT fields. At some point though, the index might become too large and start costing you performance. At which point you should pull it back a little.

So do some trial and error on the indices and you might be able to net a few more seconds.

If you want to post your full SQL, we can take a look and see if there are any other areas for optimization.
Mar 16 '12 #13

Sign in to post your reply or Sign up for a free account.

Similar topics

3
1642
by: Deano | last post by:
Ta for looking. I am setting this SQL to the recordsource of a report but it's complaining about a syntax error. "SELECT tblemp.Surname, tblemp.Forename, tblAbsence.AbsenceDate,...
0
1583
by: Tony | last post by:
Aloha, I have a problem that I can't think of a (easy) solution for. I'm building a web app (asp/access) that will allow people to book a cruise on a 24 passenger yacht that goes around the...
3
3018
by: rugger81 | last post by:
I am currently working in the sql server 2000 environment and I want to write a function to pull all dates within a given date range. I have created several diferent ways to do this but I am...
1
1843
by: Macbane | last post by:
Hi There, I have a main form that with a subform which is based on a parameter query. I have 2 controls on the main form & which are used as parameters in the query. It all works fine and...
7
6814
by: nussu | last post by:
Hi, Plz provide me javascript : javascript for a textbox to accept the values in decimals and within range i need to enter a value in textbox like 1.03 and it should be <3 (lessthan 3). Plz...
5
2447
by: Harlequin | last post by:
Hi there, I'm something of a newcomer to MS Access so it's more than likely that my question is extremely elementary. I have a form whose record source is a single table in my database. It's...
1
1804
by: DAHMB | last post by:
I have a column in a report that I want to return a sum of certain criteria from a query between two dates. I set the dates in a form that I launch the report from. My query contains a field called...
1
2313
ifedi
by: ifedi | last post by:
I've a project (medical stuff based on PHP/apache) where I need to run this query: SELECT CONCAT_WS(" ", CONCAT(pregNo,':'), del_year, MONTHNAME(CONCAT('2000-',del_month,'-01')),...
6
19785
by: Suevans | last post by:
I've written a basic query which has a calculated field Amount: - The query works fine. Sometimes it will not have anything to show, this is correct, it is for unreconciled transactions. ...
1
2859
itiger
by: itiger | last post by:
SELECT last_name, TO_CHAR(hire_date, 'DD-Mon-yyyy') from employees WHERE TO_DATE(hire_date, 'DD-Mon-YYYY') < '01-Jan-1990'; Output: LAST_NAME TO_CHAR(HIRE_DATE,'DD-MON-YYYY')...
0
7213
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7098
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7298
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7366
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7471
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5610
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5026
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3187
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1526
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.