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. -
Create Table DateTest1
-
(ID int,
-
name varchar(10),
-
datetest datetime
-
)
-
-
Create Table DateTest2
-
(
-
ID int,
-
Descripttion varchar(35)
-
)
-
-
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)
-
-
Insert into DateTest2 Values (1,'Descr 1') , (2,'Descr 2'), (3,'Descr 3'), (4,'Descr 4'), (5,'Descr 5'), (6,'Descr 6')
-
-
Select a.id, a.name, a.datetest, b.descripttion from DateTest2 b
-
Inner Join DateTest1 a on a.id = b.id
-
where a.datetest between GETDATE()- 11 and GETDATE() or
-
a.datetest is null
-
-
--Case statement does not include the Nulls
-
--where a.datetest = case When a.datetest is null then a.datetest
-
-- When a.datetest between GETDATE()- 11 and
-
-- GETDATE() then a.datetest end
-
-
--Or I can use something like this.
-
--a.datetest >= GETDATE()- 11 and a.datetest <= GETDATE() or
-
--a.datetest is null
Well you get the idea. Should I make another thread?
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.
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?
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.
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... -
declare @DateVar datetime
-
-
--set @DateVar = getdate()
-
-
Select a.id, a.name, a.datetest, b.descripttion,
-
DateFrom = dateadd(dd, -10, DATEADD(dd,DATEDIFF(dd,0,@DateVar),0)),
-
DateTo = dateadd(ms,-2,DATEADD(dd,DATEDIFF(dd,0,DATEADD(d,+1,@DateVar)),0))
-
from #DateTest2 b
-
left Join #DateTest1 a on a.id = b.id
-
where (a.datetest between dateadd(dd, -10, DATEADD(dd,DATEDIFF(dd,0,@DateVar),0)) and
-
dateadd(ms,-2,DATEADD(dd,DATEDIFF(dd,0,DATEADD(d,+1,@DateVar)),0)))
-
or @DateVar is null
-
-
Just comment out the set if you need to test it for specific date.
Happy Coding!!!
~~ CK
Ugh.. this works. I lost 6 seconds... grr.. still 20 seconds is better than 13 minutes. - isNull(Requests.ProcessingComplete,'01/01/1900') = case when Requests.ProcessingComplete is Null then '01/01/1900'
-
when Requests.ProcessingComplete between @AgeFromDate and @AgeToDate then Requests.ProcessingComplete
-
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. :)
Rabbit 12,516
Recognized Expert Moderator MVP
This will probably be faster. - ISNULL(Requests.ProcessingComplete, @AgeFromDate) BETWEEN @AgeFromDate AND @AgeToDate
I still think the UNION ALL could be faster. You should try that as well.
I found this example. Does isNull replace the COELESCE function? - SELECT *
-
FROM MyTable
-
WHERE
-
MyTable.StartDate >= COALESCE(MyTable.StartDate, "1/1/1900")
-
/* Date selected as earliest plausible constant to avoid min() lookup */
-
-
AND MyTable.EndDate <= COALESCE(MyTable.EndDate, "1/1/3001")
-
/* Date selected as latest plausible constant to avoid max() lookup */
-
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?
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.
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?
Yes. I indexed. I will reveiw them again though to make absolutely sure I didn't put the order in wrong or something.
Rabbit using - 1.ISNULL(Requests.ProcessingComplete, @AgeFromDate) BETWEEN @AgeFromDate AND @AgeToDate
-
I gained one second. Huzzah!
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.
Sign in to post your reply or Sign up for a free account.
Similar topics |
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,...
|
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...
|
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...
|
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...
|
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...
| |
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...
|
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...
|
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')),...
|
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. ...
|
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')...
|
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,...
| |
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...
|
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,...
|
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...
|
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...
|
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,...
|
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...
| |
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...
|
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 ...
| |