Subject | Re: [IBO] TIBOQuery to TClientDataSet really slow |
---|---|
Author | Tim Knipe |
Post date | 2003-09-17T14:19:58Z |
We're using integer primary keys for record-uniqueness. I can reproduce
the problem with a simple "select * from table" - it can be any table.
Also, if I set the TClientDataSet's PacketRecords property to 0 (only
retrieve metadata) it is still slow. It seems to be copying the
structure from the TIBOQuery to the TClientDataSet that causes the
problem.
Looking at the output in IB_MonitorDialog it seems to (reundantly?)
enumerate all stored procedures, and indexes first (that's over 1500
items) - that takes 3 seconds.
Preparing the actual query is fast (0.010 sec).
It seems to spend the next five minutes doing the following;
/*---
[ 17/09/2003 11:35:47 p ]
PREPARE STATEMENT
TR_HANDLE = 10512092
STMT_HANDLE = 10512436
SELECT I.RDB$RELATION_NAME
, I.RDB$INDEX_NAME
, I.RDB$UNIQUE_FLAG
, I.RDB$INDEX_TYPE
, I.RDB$FOREIGN_KEY
, ( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME ) AS CNST
, ( SELECT R.RDB$UPDATE_RULE
FROM RDB$REF_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =
( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME )) AS UR
, ( SELECT R.RDB$DELETE_RULE
FROM RDB$REF_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =
( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME )) AS DR
FROM RDB$INDICES I
WHERE NOT I.RDB$RELATION_NAME STARTING WITH 'RDB$'
PLAN (C NATURAL)
PLAN (R INDEX (RDB$INDEX_13))
PLAN (C NATURAL)
PLAN (R INDEX (RDB$INDEX_13))
PLAN (C NATURAL)
PLAN (I NATURAL)
FIELDS = [ Version 1 SQLd 8 SQLn 30
RDB$INDICES.RDB$RELATION_NAME = <NIL>
RDB$INDICES.RDB$INDEX_NAME = <NIL>
RDB$INDICES.RDB$UNIQUE_FLAG[RDB$UNIQUE_FLAG] = <NIL>
RDB$INDICES.RDB$INDEX_TYPE[RDB$INDEX_TYPE] = <NIL>
RDB$INDICES.RDB$FOREIGN_KEY = <NIL>
[CNST] = <NIL>
[UR] = <NIL>
[DR] = <NIL> ]
----*/
followed by this for every result in the query above (there are over
1000 results);
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10512436
FIELDS = [ Version 1 SQLd 8 SQLn 8
RDB$INDICES.RDB$RELATION_NAME = 'EQMODULEDEFAULT '
RDB$INDICES.RDB$INDEX_NAME = 'RDB$FOREIGN469 '
RDB$INDICES.RDB$UNIQUE_FLAG[RDB$UNIQUE_FLAG] = 0
RDB$INDICES.RDB$INDEX_TYPE[RDB$INDEX_TYPE] = 0
RDB$INDICES.RDB$FOREIGN_KEY = 'RDB$PRIMARY78 '
[CNST] = 'FK_EQMODULEDEFAULT7 '
[UR] = 'RESTRICT '
[DR] = 'RESTRICT ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
EXECUTE STATEMENT
TR_HANDLE = 10512092
STMT_HANDLE = 10517928
PARAMS = [ Version 1 SQLd 1 SQLn 1
[NAME] = 'RDB$FOREIGN469 ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
OPEN CURSOR
STMT_HANDLE = 10517928
NAME = C1125043259347358
----*/
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10517928
FIELDS = [ Version 1 SQLd 1 SQLn 1
RDB$INDEX_SEGMENTS.RDB$FIELD_NAME = 'AB2PARTY_GLID ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10517928
FIELDS = [ Version 1 SQLd 1 SQLn 1
RDB$INDEX_SEGMENTS.RDB$FIELD_NAME = 'AB2PARTY_GLID ' ]
ERRCODE = 100
----*/
/*---
[ 17/09/2003 11:38:41 p ]
CLOSE CURSOR
STMT_HANDLE = 10517928
----*
It also iterates over each result of the following , which takes 10-ish
seconds.
/*---
[ 17/09/2003 11:35:23 p ]
PREPARE STATEMENT
TR_HANDLE = 10512484
STMT_HANDLE = 10517928
SELECT R.RDB$FIELD_NAME
, R.RDB$RELATION_NAME
FROM RDB$RELATION_FIELDS R, RDB$FIELDS F
WHERE R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME
AND F.RDB$COMPUTED_SOURCE IS NOT NULL
AND NOT R.RDB$RELATION_NAME STARTING WITH 'RDB$'
ORDER BY 1 ASC
PLAN SORT (JOIN (R NATURAL,F INDEX (RDB$INDEX_2)))
FIELDS = [ Version 1 SQLd 2 SQLn 30
RDB$RELATION_FIELDS.RDB$FIELD_NAME = <NIL>
RDB$RELATION_FIELDS.RDB$RELATION_NAME = <NIL> ]
SECONDS = 0.010
----*/
Regards,
Tim Knipe
the problem with a simple "select * from table" - it can be any table.
Also, if I set the TClientDataSet's PacketRecords property to 0 (only
retrieve metadata) it is still slow. It seems to be copying the
structure from the TIBOQuery to the TClientDataSet that causes the
problem.
Looking at the output in IB_MonitorDialog it seems to (reundantly?)
enumerate all stored procedures, and indexes first (that's over 1500
items) - that takes 3 seconds.
Preparing the actual query is fast (0.010 sec).
It seems to spend the next five minutes doing the following;
/*---
[ 17/09/2003 11:35:47 p ]
PREPARE STATEMENT
TR_HANDLE = 10512092
STMT_HANDLE = 10512436
SELECT I.RDB$RELATION_NAME
, I.RDB$INDEX_NAME
, I.RDB$UNIQUE_FLAG
, I.RDB$INDEX_TYPE
, I.RDB$FOREIGN_KEY
, ( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME ) AS CNST
, ( SELECT R.RDB$UPDATE_RULE
FROM RDB$REF_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =
( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME )) AS UR
, ( SELECT R.RDB$DELETE_RULE
FROM RDB$REF_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =
( SELECT C.RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS C
WHERE C.RDB$INDEX_NAME = I.RDB$INDEX_NAME )) AS DR
FROM RDB$INDICES I
WHERE NOT I.RDB$RELATION_NAME STARTING WITH 'RDB$'
PLAN (C NATURAL)
PLAN (R INDEX (RDB$INDEX_13))
PLAN (C NATURAL)
PLAN (R INDEX (RDB$INDEX_13))
PLAN (C NATURAL)
PLAN (I NATURAL)
FIELDS = [ Version 1 SQLd 8 SQLn 30
RDB$INDICES.RDB$RELATION_NAME = <NIL>
RDB$INDICES.RDB$INDEX_NAME = <NIL>
RDB$INDICES.RDB$UNIQUE_FLAG[RDB$UNIQUE_FLAG] = <NIL>
RDB$INDICES.RDB$INDEX_TYPE[RDB$INDEX_TYPE] = <NIL>
RDB$INDICES.RDB$FOREIGN_KEY = <NIL>
[CNST] = <NIL>
[UR] = <NIL>
[DR] = <NIL> ]
----*/
followed by this for every result in the query above (there are over
1000 results);
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10512436
FIELDS = [ Version 1 SQLd 8 SQLn 8
RDB$INDICES.RDB$RELATION_NAME = 'EQMODULEDEFAULT '
RDB$INDICES.RDB$INDEX_NAME = 'RDB$FOREIGN469 '
RDB$INDICES.RDB$UNIQUE_FLAG[RDB$UNIQUE_FLAG] = 0
RDB$INDICES.RDB$INDEX_TYPE[RDB$INDEX_TYPE] = 0
RDB$INDICES.RDB$FOREIGN_KEY = 'RDB$PRIMARY78 '
[CNST] = 'FK_EQMODULEDEFAULT7 '
[UR] = 'RESTRICT '
[DR] = 'RESTRICT ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
EXECUTE STATEMENT
TR_HANDLE = 10512092
STMT_HANDLE = 10517928
PARAMS = [ Version 1 SQLd 1 SQLn 1
[NAME] = 'RDB$FOREIGN469 ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
OPEN CURSOR
STMT_HANDLE = 10517928
NAME = C1125043259347358
----*/
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10517928
FIELDS = [ Version 1 SQLd 1 SQLn 1
RDB$INDEX_SEGMENTS.RDB$FIELD_NAME = 'AB2PARTY_GLID ' ]
----*/
/*---
[ 17/09/2003 11:38:41 p ]
FETCH
STMT_HANDLE = 10517928
FIELDS = [ Version 1 SQLd 1 SQLn 1
RDB$INDEX_SEGMENTS.RDB$FIELD_NAME = 'AB2PARTY_GLID ' ]
ERRCODE = 100
----*/
/*---
[ 17/09/2003 11:38:41 p ]
CLOSE CURSOR
STMT_HANDLE = 10517928
----*
It also iterates over each result of the following , which takes 10-ish
seconds.
/*---
[ 17/09/2003 11:35:23 p ]
PREPARE STATEMENT
TR_HANDLE = 10512484
STMT_HANDLE = 10517928
SELECT R.RDB$FIELD_NAME
, R.RDB$RELATION_NAME
FROM RDB$RELATION_FIELDS R, RDB$FIELDS F
WHERE R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME
AND F.RDB$COMPUTED_SOURCE IS NOT NULL
AND NOT R.RDB$RELATION_NAME STARTING WITH 'RDB$'
ORDER BY 1 ASC
PLAN SORT (JOIN (R NATURAL,F INDEX (RDB$INDEX_2)))
FIELDS = [ Version 1 SQLd 2 SQLn 30
RDB$RELATION_FIELDS.RDB$FIELD_NAME = <NIL>
RDB$RELATION_FIELDS.RDB$RELATION_NAME = <NIL> ]
SECONDS = 0.010
----*/
Regards,
Tim Knipe