473,494 Members | 2,266 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Issues with Index, Full Scans instead

I have the following sintax:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)

this type of query is used within an store procedure that provide the
v_PartId parameter, the data type for PartId on the database is
CHAR(25) same for the parameter. The problem that I have is that this
query uses a FULL SCAN to the table instead of using the PartId index
that this table has. If I change the query to be

Select *
From Inventory
Where PartId = v_PartId

then, the index is used.

This is just a sample an not a real query within my application, but
it's to illustrate my problem, I have an application using this
sintax and running with an SQL Server and works just fine, instead of
Coalesce, I'm using the function IsNull for SQL Server. I have a lot
of store procedures using this sintax because I can't anticipate which
search criteria the users of the application are going to use, anybody
please explain why the DB2 engine doesn't like this sintax and instead
of using the index is running a FULL SCAN. I tried to change the
Coalesce for a CASE and doesn't work as well.

Thanks in advance,
Luis Fajardo
lu*********@hotmail.com
Nov 12 '05 #1
13 5655
"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
I have the following sintax:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)

this type of query is used within an store procedure that provide the
v_PartId parameter, the data type for PartId on the database is
CHAR(25) same for the parameter. The problem that I have is that this
query uses a FULL SCAN to the table instead of using the PartId index
that this table has. If I change the query to be

Select *
From Inventory
Where PartId = v_PartId

then, the index is used.

This is just a sample an not a real query within my application, but
it's to illustrate my problem, I have an application using this
sintax and running with an SQL Server and works just fine, instead of
Coalesce, I'm using the function IsNull for SQL Server. I have a lot
of store procedures using this sintax because I can't anticipate which
search criteria the users of the application are going to use, anybody
please explain why the DB2 engine doesn't like this sintax and instead
of using the index is running a FULL SCAN. I tried to change the
Coalesce for a CASE and doesn't work as well.

Thanks in advance,
Luis Fajardo
lu*********@hotmail.com


Why can't you use "is null" in DB2?
Nov 12 '05 #2
The obvious question of course is whether you have doen runstats.
Once that is settle what sort of index do you have?

If all else fails here is a magic trick:
db2set DB2_SELECTIVITY=ALL
Restart db2.
Then try this:
SELECT Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId) SELECTIVITY 0.0001

That will tell DB2 that you expect this predicate to be highly selective.

Cheers
Serge
Nov 12 '05 #3
How you will do it? I search for the IsNull and seems to me that it's
not available for DB2. Give me a sample please.

Thanks

"Mark A" <no****@nowhere.com> wrote in message news:<dY****************@news.uswest.net>...
"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
I have the following sintax:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)

this type of query is used within an store procedure that provide the
v_PartId parameter, the data type for PartId on the database is
CHAR(25) same for the parameter. The problem that I have is that this
query uses a FULL SCAN to the table instead of using the PartId index
that this table has. If I change the query to be

Select *
From Inventory
Where PartId = v_PartId

then, the index is used.

This is just a sample an not a real query within my application, but
it's to illustrate my problem, I have an application using this
sintax and running with an SQL Server and works just fine, instead of
Coalesce, I'm using the function IsNull for SQL Server. I have a lot
of store procedures using this sintax because I can't anticipate which
search criteria the users of the application are going to use, anybody
please explain why the DB2 engine doesn't like this sintax and instead
of using the index is running a FULL SCAN. I tried to change the
Coalesce for a CASE and doesn't work as well.

Thanks in advance,
Luis Fajardo
lu*********@hotmail.com


Why can't you use "is null" in DB2?

Nov 12 '05 #4
"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
How you will do it? I search for the IsNull and seems to me that it's
not available for DB2. Give me a sample please.

Thanks

"is null", not IsNull.

SELECT * FROM EMP WHERE PHONENO IS NULL;

SELECT * FROM EMP WHERE SALARY IS NOT NULL;

RTFM.
Nov 12 '05 #5
No, that's not right, Coalesce it's used slightly different. If the
first parameter is null, then it uses the second, otherwise uses the
first. The "Is Null" maybe could work in combination to CASE like
this:

Select *
From Inventory
Where PartId = CASE WHEN v_PartId IS NULL THEN PartId ELSE v_PartId
END

But this statement again doesn't use the index, full scan is executed.
This sample statement is just to ilustrate my problem, but it's not
the real query which contains many conditions. Here is a more complex
sample:

-Let's say you want to have an store procedure that you can reuse to
select your inventory by PartId, Description, Status, but you don't
know what criteria is used by your application since you provide the 3
options to your users, this is again a sample query for that:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)
And Description Like Coalesce(v_Description, Description) || '%'
And Status = Coalesce(v_Status, Status)

With this type for query, is very flexible because you can select
Inventory items with 3 search criterias at the same time:

Sample1: just PartId - to select an specific part

Sample2: Description and Status - to select all part that match the
description at certain status

Sample3: Status - to select all parts at certain status

I have this type of queries on SQL Server, and depending on what
criteria I finally use, it search with the appropiate index, DB2 it's
always running FULL SCAN.

Thanks


"Mark A" <no****@nowhere.com> wrote in message news:<GW*****************@news.uswest.net>...
"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
How you will do it? I search for the IsNull and seems to me that it's
not available for DB2. Give me a sample please.

Thanks

"is null", not IsNull.

SELECT * FROM EMP WHERE PHONENO IS NULL;

SELECT * FROM EMP WHERE SALARY IS NOT NULL;

RTFM.

Nov 12 '05 #6

"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
No, that's not right, Coalesce it's used slightly different. If the
first parameter is null, then it uses the second, otherwise uses the
first. The "Is Null" maybe could work in combination to CASE like
this:

Select *
From Inventory
Where PartId = CASE WHEN v_PartId IS NULL THEN PartId ELSE v_PartId
END

But this statement again doesn't use the index, full scan is executed.
This sample statement is just to ilustrate my problem, but it's not
the real query which contains many conditions. Here is a more complex
sample:

-Let's say you want to have an store procedure that you can reuse to
select your inventory by PartId, Description, Status, but you don't
know what criteria is used by your application since you provide the 3
options to your users, this is again a sample query for that:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)
And Description Like Coalesce(v_Description, Description) || '%'
And Status = Coalesce(v_Status, Status)

With this type for query, is very flexible because you can select
Inventory items with 3 search criterias at the same time:

Sample1: just PartId - to select an specific part

Sample2: Description and Status - to select all part that match the
description at certain status

Sample3: Status - to select all parts at certain status

I have this type of queries on SQL Server, and depending on what
criteria I finally use, it search with the appropiate index, DB2 it's
always running FULL SCAN.

Thanks

Please indicate which indexes you have on the table. Also, please indicate
which columns in the predicate "Where PartId = Coalesce(v_PartId, PartId)"
are table columns and which are variables in your program:

Nov 12 '05 #7
This is really a sample query, but to continue with the sample, lets
say that this tables has the following indexes:

PartId - Primary Key
Description - Secondary Index
Status - Third Index

PartId, Description and Status are table columns
v_PartId, v_Description, and v_Status are variables
Thanks
"Mark A" <no****@nowhere.com> wrote in message news:<3L****************@news.uswest.net>...
"LUIS FAJARDO" <lu*********@hotmail.com> wrote in message
news:78**************************@posting.google.c om...
No, that's not right, Coalesce it's used slightly different. If the
first parameter is null, then it uses the second, otherwise uses the
first. The "Is Null" maybe could work in combination to CASE like
this:

Select *
From Inventory
Where PartId = CASE WHEN v_PartId IS NULL THEN PartId ELSE v_PartId
END

But this statement again doesn't use the index, full scan is executed.
This sample statement is just to ilustrate my problem, but it's not
the real query which contains many conditions. Here is a more complex
sample:

-Let's say you want to have an store procedure that you can reuse to
select your inventory by PartId, Description, Status, but you don't
know what criteria is used by your application since you provide the 3
options to your users, this is again a sample query for that:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)
And Description Like Coalesce(v_Description, Description) || '%'
And Status = Coalesce(v_Status, Status)

With this type for query, is very flexible because you can select
Inventory items with 3 search criterias at the same time:

Sample1: just PartId - to select an specific part

Sample2: Description and Status - to select all part that match the
description at certain status

Sample3: Status - to select all parts at certain status

I have this type of queries on SQL Server, and depending on what
criteria I finally use, it search with the appropiate index, DB2 it's
always running FULL SCAN.

Thanks

Please indicate which indexes you have on the table. Also, please indicate
which columns in the predicate "Where PartId = Coalesce(v_PartId, PartId)"
are table columns and which are variables in your program:

Nov 12 '05 #8
Hi guys,

I come from a mainframe (DB2 Z/OS) platform so I don't know if my
tuning knowledge applies to the LUW platform. But it seems to me you
have a different problem.

On mainframe it would be normal that the index isn't taken. You
choose to work with the coalesce function in the where clause. This
can cause a big performance problem because : the "where" predicate
becomes non-indexable (on mainframe at least). Every time you use a
non-column scalar function it renders that predicate non-indexable...
it's just a rule of the DB2 optimizer (again I'm sure about it on
mainframe, different rules may apply on LUW).

I teach the IBM application tuning class (CF96) in Europe and this is
a classic example. You have multiple possible "where" clauses and you
don't know which the user is going to take.
you have two options (on mainframe)
1. you decide to work with dynamic SQL and you provide at least 3
indexes (one starting with col1, one starting with col2 and one with
col3)... the fact that you work dynamic the access path is chosen at
runtime depending on the where clauses left. if the customer gives 2
out of 3 possible predicates ex. col2 and col3
you construct your SQL as
select * from table where col2 = hostvar and col3 = hostvar

and you "forget" about col1. This way you're not using the coalesce
function, you create the SQL depending on the user input. you're now
left with an access path with at least MC =1 (remember the 3 indexes,
maybe even 2 depending on the rest of the index columns)

2. you decide to work with static SQL and then your access path is
determined at BIND TIME... so no matter which input the user provides
(col1, col2 or col3) DB2 will always use the same access path. A way
around this (again this is still on mainframe) either use bind option
REOPT(VARS) or take care of it in your application. This last thing
means that you evaluate whether or not the customer filled out one,
two or three fields and you write different cursors to which you
direct the application depending on the number of fields an which
fields.
This way you're sure to always have a good access path but it does
require a lot of coding just for 3 fields this means coding 8 cursors
and a 3 - 4 multi column indexes :
the 8 cursors because the following possibilities (1 means field was
filled out by client, 0 means it wasn't)
col1 col2 col3
0 0 0 select * from table
0 0 1 select * from table where col3 =
0 1 0 select * from table where col2 =
0 1 1 select * from table where col2 =...and col3 =
1 0 0 select * from table where col1 =
1 0 1 select * from table where col1 =...and col3 =
1 1 0 ....
1 1 1

I hope this can help.

Kurt Struyf
senior consultant
Competence Partners, Belgium
Nov 12 '05 #9
Ian
LUIS FAJARDO wrote:
I have the following sintax:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)


This query doesn't make much sense (to me). If v_PartID is a variable,
presumably you know the value of it _before_ you execute the query.
So why test whether it's null _in_ the query?

(Maybe this makes more sense if it's "coalesce(partid,v_partid)",
but of course if partid is your PK it can't be null, making this
predicate useless again).


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Nov 12 '05 #10
Serge Rielau <sr*****@ca.eye-bee-em.com> wrote in message news:<oa*************@news04.bloor.is.net.cable.ro gers.com>...
The obvious question of course is whether you have doen runstats.
Once that is settle what sort of index do you have?

If all else fails here is a magic trick:
db2set DB2_SELECTIVITY=ALL
Restart db2.
Then try this:
SELECT Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId) SELECTIVITY 0.0001

That will tell DB2 that you expect this predicate to be highly selective.

Cheers
Serge

I am also having this issue, but the SELECTIVITY option mentioned
above is not compatible with DB2/400. It seems to only works with
Windows/Linux UDB. Do you know how I could accomplish the same this
but while working with an AS/400?

Thanks,

Alex
Nov 12 '05 #11
I ran into this same issue on an SQL Server to UDB conversion and, after
sone discussions with the client, came up with the following explanation:

SQL Server does optimization at execute time. The optimizer recognizes
the null value for v_PartId and that PartID=PartID is a null predicate
and ignores it entirely when determining a path. UDB uses static SQL,
binding at compile time, when the actual data values for the variables
are not available. The queries you are writing will always end up
causing table scans.

The only way around this is to use dynamic SQL, determining which
predicate variable is not null and using that variable to construct the
SQL predicate.

As pointed out in prior responses, setting up a number of queries, each
optimized for a different index, can also be a useful solution. In this
case, the non-null variable is used to select which query is executed.
Check all queries with EXPLAIN to make sure that the optimizer doesn't
decide to do a scan anyway.

Phil Sherman

LUIS FAJARDO wrote:
I have the following sintax:

Select *
From Inventory
Where PartId = Coalesce(v_PartId, PartId)

this type of query is used within an store procedure that provide the
v_PartId parameter, the data type for PartId on the database is
CHAR(25) same for the parameter. The problem that I have is that this
query uses a FULL SCAN to the table instead of using the PartId index
that this table has. If I change the query to be

Select *
From Inventory
Where PartId = v_PartId

then, the index is used.

This is just a sample an not a real query within my application, but
it's to illustrate my problem, I have an application using this
sintax and running with an SQL Server and works just fine, instead of
Coalesce, I'm using the function IsNull for SQL Server. I have a lot
of store procedures using this sintax because I can't anticipate which
search criteria the users of the application are going to use, anybody
please explain why the DB2 engine doesn't like this sintax and instead
of using the index is running a FULL SCAN. I tried to change the
Coalesce for a CASE and doesn't work as well.

Thanks in advance,
Luis Fajardo
lu*********@hotmail.com


Nov 12 '05 #12
Luis,

I think this is what Mark means:

WHERE partid = vpartid OR vpartid IS NULL

Either way I don't think teh technique you use is appropriate.
You try to fit many options of input into one query.
Keep in mind that teh optimizer can only choose one plan for all these
options.
It woudl be more appropriate to "compose" the query given the variable
provided:

Something like:
SET stmt = 'SELECT * FROM T WHERE ';
IF vpartid IS NOT NULL THEN
SET stmt = stmt || 'partid = ? ';
END ID;
IF ....

PREPARE ...

BTW, I do not buy that SQL Server does teh right plan al teh time
because when vpartid IS NULL the a table scan IS the better plan.

Does DB2 for AS/400 support the VOLATAILE keyword on CREATE TABLE?
It is defined to encourage index usage.

Cheers
Serge
Nov 12 '05 #13
We switch to dynamic sql ("compose" the query) and that fixed our
problem. Thanks for your help.
Serge Rielau <sr*****@ca.eye-bee-em.com> wrote in message news:<rM*****************@news04.bloor.is.net.cabl e.rogers.com>...
Luis,

I think this is what Mark means:

WHERE partid = vpartid OR vpartid IS NULL

Either way I don't think teh technique you use is appropriate.
You try to fit many options of input into one query.
Keep in mind that teh optimizer can only choose one plan for all these
options.
It woudl be more appropriate to "compose" the query given the variable
provided:

Something like:
SET stmt = 'SELECT * FROM T WHERE ';
IF vpartid IS NOT NULL THEN
SET stmt = stmt || 'partid = ? ';
END ID;
IF ....

PREPARE ...

BTW, I do not buy that SQL Server does teh right plan al teh time
because when vpartid IS NULL the a table scan IS the better plan.

Does DB2 for AS/400 support the VOLATAILE keyword on CREATE TABLE?
It is defined to encourage index usage.

Cheers
Serge

Nov 12 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
15523
by: ryan | last post by:
Hi Everyone, I'm having trouble convincing myself that Oracle is executing a query of mine as efficiently as possible, and I'm looking for a little guidance. The situation is pretty simple. I...
1
2693
by: sumGirl | last post by:
Hi all. Anyone know if sql server collects stats on how many full table scans a table gets and if so how do I get at those stats? Trying to track down poorly indexed tables / processes and I am...
4
1531
by: DC | last post by:
When a nonunique nonclustered index is built on top of a clustered index, is it guaranteed that the bookmark in the nonclustered index will be kept in the same order as the clustered index? ...
5
17294
by: Bas Scheffers | last post by:
Hi, I have a table with about 100K rows, on which I have created a btree index of the type table_name(int, int, int, timestamp). At first postgres was using it for my AND query on all four...
7
2200
by: teddysnips | last post by:
Table DDL below: The tables I have contain Timesheet information. Each row in the tblTSCollected table contains an entry for an employee into the timesheet system, specifically by scanning the...
6
2511
by: db2admin | last post by:
hi, i have query doing tablescan instead index scan. i would explain situation in more detail. table has MDC on one column and three more regular indexes. now, one of the index which has three...
4
5146
by: p175 | last post by:
What are the advantages / disadvantages of having primary keys in lieu of ordinary indexes ? If there are no foreign relationships defined, is it better to have a two column index allowing reverse...
0
1064
by: Xexon | last post by:
Hey all, I hope someone out there has got a solution to this rather irritating problem :) Ok here it goes... I have a Web App that does 2 things. It uploads word-document files to a folder on my...
2
1963
by: cherukuc | last post by:
We have a unique issue where a query does a tablescan even though an index is present. Basically we created a new DB by loading existing data from a source DB. The index names and everything else...
0
7119
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
6989
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
7157
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
7195
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
7367
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...
1
4889
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
4579
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3088
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
1400
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.