By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,921 Members | 1,471 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,921 IT Pros & Developers. It's quick & easy.

select * from table AND navigation

P: n/a
TP
Here is my problem.

I need to display a table about which I have no information except the
table name. Using metadata I can somehow show the column names and
record values.

But my table has 1 million rows and if I do a select * then I do get
1 million rows.

I want to be able to provide page navigation as google does, page
forward, backwards etc. For now it is a read only database.

For reference please see my post here.
http://forum.java.sun.com/thread.jsp...essage=2252212

I would appreciate any ideas. I have been stuck for a week now.

Thanks.

TP
Nov 12 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
select count(*) will tell you how many rows it has. DESCRIBE TABLE
table_name will give you info on columns and data types.

TP wrote:
Here is my problem.

I need to display a table about which I have no information except the
table name. Using metadata I can somehow show the column names and
record values.

But my table has 1 million rows and if I do a select * then I do get
1 million rows.

I want to be able to provide page navigation as google does, page
forward, backwards etc. For now it is a read only database.

For reference please see my post here.
http://forum.java.sun.com/thread.jsp...essage=2252212

I would appreciate any ideas. I have been stuck for a week now.

Thanks.

TP


Nov 12 '05 #2

P: n/a
AK
Let us consider a very common situation. A GUI application issues a
query, then the first 25 rows from the result set are diplayed on
screen. If the user presses Page Down, then the next 25 rows will be
displayed, and so on. It is well known that FETCH FIRST 25 ROWS and
OPTIMIZE FOR 25 ROWS clauses of SELECT statement are very useful in
this situation. In fact, using either of them is a straightforward way
to tell the optimizer what you actually need. The optimizer, in its
turn, might choose an entirely different access plan to satisfy a
query with such a clause. For example, the query

SELECT * FROM CUSTOMER ORDER BY LAST_NAME

may be satisfied by a tablespace scan, followed by a sort. As a
result, the initial response time may be quite high. However, this is
the fastest way to retrieve the whole result set. Adding an OPTIMIZE
FOR, as well as FETCH FIRST, clause may cause the optimizer to choose
an index access plan, so that the first 25 rows are returned as soon
as possible. The immediate response time usually comes at a price:
should we ever need to retrieve all the rows, the overall execution
time would be high. It could be significantly higher than the
execution time of a tablespace scan.

You may also have come across the advice to use an OLAP function
ROW_NUMBER() to limit the output to 25 rows at a time. This advice is
more controversial. Let us discuss it in more detail and see its
potential drawbacks. If you use Visual Explain to compare execution
plans of these two statements:

SELECT ROW_NUMBER() OVER() AS N, S.* FROM SALES_DETAIL S WHERE N
BETWEEN 26 AND 50;

SELECT * FROM SALES_DETAIL FETCH FIRST 50 ROWS ONLY

you will not notice much difference. Both plans will be tablespace
scans. If you run these two queries against a small table, you will
not notice much difference in response time either. Although the plans
look very similar, the actual execution is quite different:

the first statement will scan the whole table, checking every row
against the criteria N BETWEEN 26 AND 50
the second statement will also start scanning the whole table, but the
scanning will stop as soon as the required amount of rows is
retrieved.

Do not assume that these 2 statements will perform equally well
against a big table. If you use db2batch utility to measure real
execution costs, you will be able to detect the difference: the first
statement will scan the whole table, while the second one will read
just several data pages containing the first 25 rows. Should the table
in production environment grow really big, the difference would be
dramatic, so it is usually a good idea to test your application
against realistically big amounts of data from the early stages of
development.

As we have seen, FETCH FIRST and OPTIMIZE FOR clauses are usually more
appropriate for limiting amount of rows if the result set may be big.
Also I have demonstrated the importance of considering both execution
plan and real execution costs.
Nov 12 '05 #3

P: n/a
TP
Hey,

Thanks for your reply.

I tried the
---------------------------------------------------
select ROW_NUMBER() OVER() AS N, S.* FROM from P390V.FUND s WHERE N
BETWEEN 26 AND 50
---------------------------------------------------
but I got this error
---------------------------------------------------
DBA2191E SQL execution error.

com.ibm.db.DataException: A database manager error occurred. :
[IBM][CLI Driver][DB2] SQL0104N An unexpected token "(" was found
following "". Expected tokens may include: ", FROM INTO ".
SQLSTATE=42601
---------------------------------------------------
That aside, when you say

SELECT * FROM SALES_DETAIL FETCH FIRST 50 ROWS ONLY

and the database gets me 50 rows. how will this help me navigate to
the next 50 rows. I mean how can I say

SELECT * FROM SALES_DETAIL FETCH (the next) 50 ROWS ONLY (now)

and so on?

Thanks for your help.

TP.
ak************@yahoo.com (AK) wrote in message news:<46**************************@posting.google. com>...
Let us consider a very common situation. A GUI application issues a
query, then the first 25 rows from the result set are diplayed on
screen. If the user presses Page Down, then the next 25 rows will be
displayed, and so on. It is well known that FETCH FIRST 25 ROWS and
OPTIMIZE FOR 25 ROWS clauses of SELECT statement are very useful in
this situation. In fact, using either of them is a straightforward way
to tell the optimizer what you actually need. The optimizer, in its
turn, might choose an entirely different access plan to satisfy a
query with such a clause. For example, the query

SELECT * FROM CUSTOMER ORDER BY LAST_NAME

may be satisfied by a tablespace scan, followed by a sort. As a
result, the initial response time may be quite high. However, this is
the fastest way to retrieve the whole result set. Adding an OPTIMIZE
FOR, as well as FETCH FIRST, clause may cause the optimizer to choose
an index access plan, so that the first 25 rows are returned as soon
as possible. The immediate response time usually comes at a price:
should we ever need to retrieve all the rows, the overall execution
time would be high. It could be significantly higher than the
execution time of a tablespace scan.

You may also have come across the advice to use an OLAP function
ROW_NUMBER() to limit the output to 25 rows at a time. This advice is
more controversial. Let us discuss it in more detail and see its
potential drawbacks. If you use Visual Explain to compare execution
plans of these two statements:

SELECT ROW_NUMBER() OVER() AS N, S.* FROM SALES_DETAIL S WHERE N
BETWEEN 26 AND 50;

SELECT * FROM SALES_DETAIL FETCH FIRST 50 ROWS ONLY

you will not notice much difference. Both plans will be tablespace
scans. If you run these two queries against a small table, you will
not notice much difference in response time either. Although the plans
look very similar, the actual execution is quite different:

the first statement will scan the whole table, checking every row
against the criteria N BETWEEN 26 AND 50
the second statement will also start scanning the whole table, but the
scanning will stop as soon as the required amount of rows is
retrieved.

Do not assume that these 2 statements will perform equally well
against a big table. If you use db2batch utility to measure real
execution costs, you will be able to detect the difference: the first
statement will scan the whole table, while the second one will read
just several data pages containing the first 25 rows. Should the table
in production environment grow really big, the difference would be
dramatic, so it is usually a good idea to test your application
against realistically big amounts of data from the early stages of
development.

As we have seen, FETCH FIRST and OPTIMIZE FOR clauses are usually more
appropriate for limiting amount of rows if the result set may be big.
Also I have demonstrated the importance of considering both execution
plan and real execution costs.

Nov 12 '05 #4

P: n/a
AK
maybe ROW_NUMBER() does not work on your platrom. I was spaking about V8.1 onLUW

I would try OPTIMIZE FOR clAUSE
Nov 12 '05 #5

P: n/a
TP wrote:

Hey,

Thanks for your reply.

I tried the
---------------------------------------------------
select ROW_NUMBER() OVER() AS N, S.* FROM from P390V.FUND s WHERE N
BETWEEN 26 AND 50
---------------------------------------------------
but I got this error
---------------------------------------------------
DBA2191E SQL execution error.

com.ibm.db.DataException: A database manager error occurred. :
[IBM][CLI Driver][DB2] SQL0104N An unexpected token "(" was found
following "". Expected tokens may include: ", FROM INTO ".
SQLSTATE=42601
---------------------------------------------------
That aside, when you say

SELECT * FROM SALES_DETAIL FETCH FIRST 50 ROWS ONLY

and the database gets me 50 rows. how will this help me navigate to
the next 50 rows. I mean how can I say

SELECT * FROM SALES_DETAIL FETCH (the next) 50 ROWS ONLY (now)

and so on?

Thanks for your help.

TP.

ak************@yahoo.com (AK) wrote in message news:<46**************************@posting.google. com>...
Let us consider a very common situation. A GUI application issues a
query, then the first 25 rows from the result set are diplayed on
screen. If the user presses Page Down, then the next 25 rows will be
displayed, and so on. It is well known that FETCH FIRST 25 ROWS and
OPTIMIZE FOR 25 ROWS clauses of SELECT statement are very useful in
this situation. In fact, using either of them is a straightforward way
to tell the optimizer what you actually need. The optimizer, in its
turn, might choose an entirely different access plan to satisfy a
query with such a clause. For example, the query

SELECT * FROM CUSTOMER ORDER BY LAST_NAME

may be satisfied by a tablespace scan, followed by a sort. As a
result, the initial response time may be quite high. However, this is
the fastest way to retrieve the whole result set. Adding an OPTIMIZE
FOR, as well as FETCH FIRST, clause may cause the optimizer to choose
an index access plan, so that the first 25 rows are returned as soon
as possible. The immediate response time usually comes at a price:
should we ever need to retrieve all the rows, the overall execution
time would be high. It could be significantly higher than the
execution time of a tablespace scan.

You may also have come across the advice to use an OLAP function
ROW_NUMBER() to limit the output to 25 rows at a time. This advice is
more controversial. Let us discuss it in more detail and see its
potential drawbacks. If you use Visual Explain to compare execution
plans of these two statements:

SELECT ROW_NUMBER() OVER() AS N, S.* FROM SALES_DETAIL S WHERE N
BETWEEN 26 AND 50;

SELECT * FROM SALES_DETAIL FETCH FIRST 50 ROWS ONLY

you will not notice much difference. Both plans will be tablespace
scans. If you run these two queries against a small table, you will
not notice much difference in response time either. Although the plans
look very similar, the actual execution is quite different:

the first statement will scan the whole table, checking every row
against the criteria N BETWEEN 26 AND 50
the second statement will also start scanning the whole table, but the
scanning will stop as soon as the required amount of rows is
retrieved.

Do not assume that these 2 statements will perform equally well
against a big table. If you use db2batch utility to measure real
execution costs, you will be able to detect the difference: the first
statement will scan the whole table, while the second one will read
just several data pages containing the first 25 rows. Should the table
in production environment grow really big, the difference would be
dramatic, so it is usually a good idea to test your application
against realistically big amounts of data from the early stages of
development.

As we have seen, FETCH FIRST and OPTIMIZE FOR clauses are usually more
appropriate for limiting amount of rows if the result set may be big.
Also I have demonstrated the importance of considering both execution
plan and real execution costs.


select * from (select ROW_NUMBER() OVER() AS N, S.* FROM P390V.FUND s)
as dummy WHERE N BETWEEN 26 AND 50

I would prefer

select * from (select ROW_NUMBER() OVER(order by <keycolumn#1>, ...,
<keycolumn#N>) AS N, S.* FROM P390V.FUND s) as dummy WHERE N BETWEEN 26
AND 50
--
Dieter Wagner Di***********@tde-online.de
Software Development Group I TDE - Tele Data Electronic GmbH
Durmersheim, Germany
Nov 12 '05 #6

P: n/a
AK
>
select * from (select ROW_NUMBER() OVER() AS N, S.* FROM P390V.FUND s)
as dummy WHERE N BETWEEN 26 AND 50

I would prefer

select * from (select ROW_NUMBER() OVER(order by <keycolumn#1>, ...,
<keycolumn#N>) AS N, S.* FROM P390V.FUND s) as dummy WHERE N BETWEEN 26
AND 50


if you have a look at real execution costs, yu'll see that the whole
table is scanned to retrieve 25 rows. Very inefficient. Use OPTIMIZE
FOR or FETCH FIRST
Nov 12 '05 #7

P: n/a
AK wrote:


if you have a look at real execution costs, yu'll see that the whole
table is scanned to retrieve 25 rows. Very inefficient. Use OPTIMIZE
FOR or FETCH FIRST
OK it's inefficient, but it works.
In your former posting you wrote
SELECT ROW_NUMBER() OVER() AS N, S.* FROM SALES_DETAIL S WHERE N
BETWEEN 26 AND 50;

This doesn't work. My command line interpreter (DB2 7.2.8, AIX) told
me:
db2 => SELECT ROW_NUMBER() OVER() AS N, S.* FROM lzgneu.mdst S WHERE N
BETWEEN 26 AND 50;
SQL0206N "N" is not valid in the context where it is used.
SQLSTATE=4270

How does the correct statement look like?
--
Dieter Wagner Di***********@tde-online.de
Software Development Group I TDE - Tele Data Electronic GmbH
Durmersheim, Germany
Nov 12 '05 #8

P: n/a
If memory serves mes good, ROW_NUMBER() was introduced in v6..

PM

"AK" <ak************@yahoo.com> a écrit dans le message de
news:46*************************@posting.google.co m...
maybe ROW_NUMBER() does not work on your platrom. I was spaking about V8.1 onLUW
I would try OPTIMIZE FOR clAUSE

Nov 12 '05 #9

P: n/a
Correct - documented in the release notes for DB2 Linux/UNIX/Windows:

ftp://ftp.software.ibm.com/ps/produc...02/release.txt

PM (pm3iinc-nospam) wrote:
If memory serves mes good, ROW_NUMBER() was introduced in v6..

PM

"AK" <ak************@yahoo.com> a écrit dans le message de
news:46*************************@posting.google.co m...
maybe ROW_NUMBER() does not work on your platrom. I was spaking about V8.1


onLUW
I would try OPTIMIZE FOR clAUSE



Nov 12 '05 #10

P: n/a
> I tried the
---------------------------------------------------
select ROW_NUMBER() OVER() AS N, S.* FROM from P390V.FUND s WHERE N
BETWEEN 26 AND 50
---------------------------------------------------
but I got this error
---------------------------------------------------
DBA2191E SQL execution error.

com.ibm.db.DataException: A database manager error occurred. :
[IBM][CLI Driver][DB2] SQL0104N An unexpected token "(" was found
following "". Expected tokens may include: ", FROM INTO ".
SQLSTATE=42601
---------------------------------------------------

Your DB2 may not support ROW_NUMBER.
But if your DB2 support ROW_NUMBER, you should use nested table expression.
SELECT *
FROM (SELECT ROW_NUMBER() OVER() AS N, S.* FROM P390V.FUND s) s
WHERE N BETWEEN 26 AND 50
Nov 12 '05 #11

P: n/a
AK
Dieter,

my point is different:
OPTIMIZE FOR and FETCH FIRST usually perform much better

maybe
SELECT (ROW_NUMBER() OVER()) AS N ...
could work on V7?

I only have V8 and can't verify
Nov 12 '05 #12

P: n/a
TP
I wish I could tell you if it does support row_number(), but I really
cannot for sure (woah me). When I open up my command center, on
connect, it tells me DB2 version 7.1.1 for os390.

But as far as this problem is concerned. I have gone the round route.

First get the table primary keys from sysibm tables, then do a order
by pk, fetch first 10 where pk_value is greater than the last highest
one shown. I am doing this for next navigation or forward navigation.

The thing with this approach is that I can keep track of the last
shown value and achieve first, previous, next and last row navigation.

Any ideas to optimize this further?

Thanks.

TP
to*****@jp.ibm.com (Tokunaga T.) wrote in message news:<81*************************@posting.google.c om>...
I tried the
---------------------------------------------------
select ROW_NUMBER() OVER() AS N, S.* FROM from P390V.FUND s WHERE N
BETWEEN 26 AND 50
---------------------------------------------------
but I got this error
---------------------------------------------------
DBA2191E SQL execution error.

com.ibm.db.DataException: A database manager error occurred. :
[IBM][CLI Driver][DB2] SQL0104N An unexpected token "(" was found
following "". Expected tokens may include: ", FROM INTO ".
SQLSTATE=42601
---------------------------------------------------

Your DB2 may not support ROW_NUMBER.
But if your DB2 support ROW_NUMBER, you should use nested table expression.
SELECT *
FROM (SELECT ROW_NUMBER() OVER() AS N, S.* FROM P390V.FUND s) s
WHERE N BETWEEN 26 AND 50

Nov 12 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.