Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 WHERE UserID IN (...)

Author  Topic 

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-16 : 08:57:23
I have an update statement which basically updates a table based on some summed money-columns. The update has something like this in the end:

...
WHERE UserID = @UserID_1 OR UserID = @UserID_2
GROUP BY UserID

I used to have just "WHERE UserID = @UserID" which used a nice Clustered index seek, but when I added the "OR UserID = @UserID_2" the plan changed into a scan. Is there anything I can do to have t use a seek instead? I have tried with "UserID IN (@UserID_1, @UserID_2)" also but without much luck.

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"

gpl
Posting Yak Master

195 Posts

Posted - 2004-09-16 : 09:28:07
Try popping your user ids into a temp table (with index) - then join your main table with it

Graham
Go to Top of Page

samsekar
Constraint Violating Yak Guru

437 Posts

Posted - 2004-09-16 : 09:57:36
How many records your query returns ? if it is more relative to the total no of records, then clustered index scan is prefered.

- Sekar
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-16 : 10:00:14
well, it depends...could be anything from 0 to a few hundred...

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

kselvia
Aged Yak Warrior

526 Posts

Posted - 2004-09-16 : 13:40:40
You can split the query into two queries and they will get different plans
...
WHERE UserID = @UserID_1
GROUP BY UserID

UNION ALL
...
WHERE UserID = @UserID_2
GROUP BY UserID

--Ken
I want to die in my sleep like my grandfather, not screaming in terror like his passengers.
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-17 : 05:01:55
But Ken, if I use the UNION ALL woun't the query process actually be run twice, once for each and then joined together? I would think that this would be worse performancewise but I really don't know.

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2004-09-17 : 05:06:00
have you tried using an index hint?

just an idea...
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-17 : 05:12:14
Hm, haven't tried it in this case actually but it might be worth a shot. I try to avoid them but maybe it will do some good here...I'll let you know :)

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

kselvia
Aged Yak Warrior

526 Posts

Posted - 2004-09-17 : 12:24:55
quote:
Originally posted by Lumbago

But Ken, if I use the UNION ALL woun't the query process actually be run twice, once for each and then joined together? I would think that this would be worse performancewise but I really don't know.


Yes it would be run twice but that might be the most efficient way to do it. The only to know is to try it. From http://www.sql-server-performance.com/transact_sql.asp
quote:

A query with one or more OR clauses can sometimes be rewritten as a series of queries that are combined with a UNION ALL statement, in order to boost the performance of the query. For example, let's take a look at the following query:

SELECT employeeID, firstname, lastname
FROM names
WHERE dept = 'prod' or city = 'Orlando' or division = 'food'

This query has three separate conditions in the WHERE clause. In order for this query to use an index, then there must be an index on all three columns found in the WHERE clause.

This same query can be written using UNION ALL instead of OR, like this example:

SELECT employeeID, firstname, lastname FROM names WHERE dept = 'prod'
UNION ALL
SELECT employeeID, firstname, lastname FROM names WHERE city = 'Orlando'
UNION ALL
SELECT employeeID, firstname, lastname FROM names WHERE division = 'food'

Each of these queries will produce the same results. If there is only an index on dept, but not the other columns in the WHERE clause, then the first version will not use any index and a table scan must be performed. But in the second version of the query will use the index for part of the query, but not for all of the query.




--Ken
I want to die in my sleep like my grandfather, not screaming in terror like his passengers.
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-09-17 : 14:25:03
I don't know about the article itself, but that's a bad example to use.

The queries shown are not equivalent -- with the UNION ALL it will return duplicate rows for a situation in which more than 1 part of the WHERE clause is true. And if you switch to UNION instead of UNION ALL, you get a big performance hit.

So I am not sure that you can justify using a UNION in that specific example -- in fact, you SHOULDN'T -- the results will not be what you intended.

- Jeff
Go to Top of Page

kselvia
Aged Yak Warrior

526 Posts

Posted - 2004-09-17 : 14:32:24
Hmm Jeff is right. The technique is only useful where the criteria are mutually exclusive (as in your example) I knew I had read an article about it and I just pasted their example, but as Jeff noted - that is a bad example. I'm a bit suprised. They are usually correct over there at sql-server-performance.com

--Ken
I want to die in my sleep like my grandfather, not screaming in terror like his passengers.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-09-18 : 06:32:38
I expect tou know this, but.

I stick

SET STATISTICS IO ON; SET STATISTICS TIME ON
... stuff here ...
SET STATISTICS IO OFF; SET STATISTICS TIME OFF

around the bits I want to test, then I look at the Scan Count and Logical Reads - and try to get them smaller!

Kristen
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-18 : 07:07:04
You should not expect anything with a semirookie like myself, but I have given them a glance or two :) Any rules of thumb I should follow? A wise man once told me something in the area of less than 4 logical reads per scan count or something...

And another thing: how important is it to have alot of actual data in the tables while testing? I usually fill the tables manually with up to maybe 30 rows just to test if my queries actually get the data they are supposed to, and then look at indexes and plans to decide their efficiency. Would it be better if I filled them with a few million rows? Should I expect any different results?

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-09-18 : 07:14:59
DEV is one thing, TEST another - IMHO.

For TEST I want a copy of the real data. Then I can fine tune the queries. You may very well get a different query plan with lots of data.

I don't have a hard and fast rule for what the numbers should be, but the moment the indexes don't get used the Logical Reads goes through the roof :-)

So I find this method useful for twiddling with the query and seeing how the logical reads adjust. I suggest you try each of the suggestions here and keep an eye on the Logical Reads for each one.

"Would it be better if I filled them with a few million rows? Should I expect any different results?"

I think the key to this is that the real data may change the granularity of the data, that in turn may cause the query planner to chosoe a different method.

Kristen
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-09-18 : 07:39:42
Ok, so since there is no difference between development and test (we are only a tiny company) you recomend that I first do the development, and when I am confident that the database design is correct I should fill the tables with data and then do additional testing?

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2004-09-18 : 10:25:00
That would be my plan.

As you are small and if the data is readily available I'd put that in my DEV system (if security is not an issue amongst the developers, AND you are not going to accidenatlly EMail the actual user's email address etc.!!)

Kristen
Go to Top of Page
   

- Advertisement -