Advice needed for reccount() in scopped and filtered dbfcdx.
- lucasdebeltran
- Posts: 1303
- Joined: Tue Jul 21, 2009 8:12 am
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Dear Mr. Nages,
From previous posts from you I understood that SET DELETED ON in a network scenareo and xBrowse causes some delay, so that´s the reason to include the For !Deleted() clause on the index command.
Is it correct?.
Thank you.
From previous posts from you I understood that SET DELETED ON in a network scenareo and xBrowse causes some delay, so that´s the reason to include the For !Deleted() clause on the index command.
Is it correct?.
Thank you.
Muchas gracias. Many thanks.
Un saludo, Best regards,
Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]
Implementando MSVC 2010, FWH64 y ADO.
Abandonando uso xHarbour y SQLRDD.
Un saludo, Best regards,
Harbour 3.2.0dev, Borland C++ 5.82 y FWH 13.06 [producción]
Implementando MSVC 2010, FWH64 y ADO.
Abandonando uso xHarbour y SQLRDD.
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
This sample:
displays this without filter
and this with filter:
So I don't see any optimization...
EMG
Code: Select all | Expand
REQUEST DBFCDX
FUNCTION MAIN()
LOCAL nSec, nKey
RDDSETDEFAULT( "DBFCDX" )
IF !FILE( "CORSE.CDX" )
USE CORSE
INDEX ON DTOS( FIELD -> data ) + UPPER( FIELD -> cliente ) TO CORSE
CLOSE
ENDIF
USE CORSE INDEX CORSE
SET FILTER TO FIELD -> cliente = "A"
nSec = SECONDS()
nKey = ORDKEYCOUNT()
? SECONDS() - nSec, nKey
CLOSE
RETURN NIL
displays this without filter
Code: Select all | Expand
0.00 910404
and this with filter:
Code: Select all | Expand
2.20 58776
So I don't see any optimization...

EMG
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Enrico,
Hmm, you can't compare with and without a filter to see optimization. It seems you would have to compare the filter compiled with xHarbour (with optimization) v.s. Clipper (without optimization).
James
Hmm, you can't compare with and without a filter to see optimization. It seems you would have to compare the filter compiled with xHarbour (with optimization) v.s. Clipper (without optimization).
James
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
James,
understood. Can't test with Clipper anymore, sorry.
EMG
understood. Can't test with Clipper anymore, sorry.

EMG
- nageswaragunupudi
- Posts: 10733
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 10 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Because this filter
can not be optimized at all.
As I said earlier, DBFCDX provides capabilities of optimization, provided the programmer wants to avail the benefits of these capabilities. In this case we can not say DBFCDX is slow.
If there is an index on CLIENTE then SET FILTER TO CLIENTE = "A" can be fully optimized.
If there is an index on UPPER(CLIENTE) then SET FILTER TO UPPER(CLIENTE) = 'A' can be fully optimized.
The guidelines I indicated above to set optimized filters/where clauses are universal and are applicable to all RDBMSs as well.
Code: Select all | Expand
SET FILTER TO FIELD -> cliente = "A"
can not be optimized at all.
As I said earlier, DBFCDX provides capabilities of optimization, provided the programmer wants to avail the benefits of these capabilities. In this case we can not say DBFCDX is slow.
If there is an index on CLIENTE then SET FILTER TO CLIENTE = "A" can be fully optimized.
If there is an index on UPPER(CLIENTE) then SET FILTER TO UPPER(CLIENTE) = 'A' can be fully optimized.
The guidelines I indicated above to set optimized filters/where clauses are universal and are applicable to all RDBMSs as well.
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Rao,
If I had an index on UPPER(CLIENTE) I wouldn't need of filters at all. I would just use scopes. We can't have an index for any possible filter.
EMG
nageswaragunupudi wrote:If there is an index on CLIENTE then SET FILTER TO CLIENTE = "A" can be fully optimized.
If there is an index on UPPER(CLIENTE) then SET FILTER TO UPPER(CLIENTE) = 'A' can be fully optimized.
If I had an index on UPPER(CLIENTE) I wouldn't need of filters at all. I would just use scopes. We can't have an index for any possible filter.
EMG
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Enrico,
Consider:
Assuming there is an index on client, then this should be optimized:
set filter to client ="A" .or. client="M"
And I don't think you can do this with scopes.
James
Consider:
Assuming there is an index on client, then this should be optimized:
set filter to client ="A" .or. client="M"
And I don't think you can do this with scopes.
James
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Rao,
I don't see any speed improvement in the modified sample below.
EMG
nageswaragunupudi wrote:If there is an index on CLIENTE then SET FILTER TO CLIENTE = "A" can be fully optimized.
If there is an index on UPPER(CLIENTE) then SET FILTER TO UPPER(CLIENTE) = 'A' can be fully optimized.
I don't see any speed improvement in the modified sample below.

Code: Select all | Expand
REQUEST DBFCDX
FUNCTION MAIN()
LOCAL nSec, nKey
RDDSETDEFAULT( "DBFCDX" )
IF !FILE( "CORSE.CDX" )
USE CORSE
INDEX ON UPPER( FIELD -> cliente ) TO CORSE
CLOSE
ENDIF
USE CORSE INDEX CORSE
nSec = SECONDS()
SET FILTER TO UPPER( FIELD -> cliente ) = "A"
nKey = ORDKEYCOUNT()
? SECONDS() - nSec, nKey
CLOSE
RETURN NIL
EMG
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
James,
Assuming that the filter above could be optimized, it would only be a specific case. Imagine a dialog full of GETs. You want your user to search on any fields and combinations. You just can't create such a number of indexes, can you?
EMG
James Bott wrote:Consider:
Assuming there is an index on client, then this should be optimized:
set filter to client ="A" .or. client="M"
And I don't think you can do this with scopes.
Assuming that the filter above could be optimized, it would only be a specific case. Imagine a dialog full of GETs. You want your user to search on any fields and combinations. You just can't create such a number of indexes, can you?
EMG
- James Bott
- Posts: 4840
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Enrico,
Agreed, but I don't see any logical way you can search for any combination of fields in a filter without reading all the records for at least some of the combinations.
I think the point is, that some filters will be optimized if there is a useful index. And this is better than no optimization ever--which was the old way.
You also have to consider probability. There are a few combinations of fields that users will search often, and some that they will never search. Think of the 80/20 rule-- 20% of the combinations will be searched 80% of the time. You could log the searches for awhile, then make sure you have indexes that will help in those 20% of the cases. Hmm, now if you wanted to get really sophisticated, you could build a routine that automatically tracks the searches and then designs indexes to speed them up. I like it.
You want your user to search on any fields and combinations.
Agreed, but I don't see any logical way you can search for any combination of fields in a filter without reading all the records for at least some of the combinations.
I think the point is, that some filters will be optimized if there is a useful index. And this is better than no optimization ever--which was the old way.
You also have to consider probability. There are a few combinations of fields that users will search often, and some that they will never search. Think of the 80/20 rule-- 20% of the combinations will be searched 80% of the time. You could log the searches for awhile, then make sure you have indexes that will help in those 20% of the cases. Hmm, now if you wanted to get really sophisticated, you could build a routine that automatically tracks the searches and then designs indexes to speed them up. I like it.
- nageswaragunupudi
- Posts: 10733
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 10 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Will you kindly try this sample as it is without changes?
Code: Select all | Expand
REQUEST DBFCDX
FUNCTION MAIN()
FIELD CLIENTE
LOCAL nSec, nKey
RDDSETDEFAULT( "DBFCDX" )
FERASE( "CORSE.CDX" )
USE CORSE EXCLUSIVE
INDEX ON UPPER(CLIENTE) TAG CLIENTE
INDEX ON DELETED() TAG DELETED
CLOSE
USE CORSE SHARED
nSec = SECONDS()
SET FILTER TO UPPER(CLIENTE) = "A" .AND. !DELETED()
nKey = ORDKEYCOUNT()
? SECONDS() - nSec, nKey
CLOSE
RETURN NIL
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
James,
I've always used conditional indexes created "on the fly" with very good results. The searches demanded by my clients are normally very complex, requiring functions calls inside the key and the FOR conditions.
EMG
James Bott wrote:Agreed, but I don't see any logical way you can search for any combination of fields in a filter without reading all the records for at least some of the combinations.
I've always used conditional indexes created "on the fly" with very good results. The searches demanded by my clients are normally very complex, requiring functions calls inside the key and the FOR conditions.
EMG
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Rao,
Yes, there is a speed improvement:
OLD
NEW
This is my modified sample:
As you can see, the only required change is SET ORDER TO 0.
EMG
nageswaragunupudi wrote:Will you kindly try this sample as it is without changes?
Yes, there is a speed improvement:
OLD
Code: Select all | Expand
2.20 58776
NEW
Code: Select all | Expand
1.84 58776
This is my modified sample:
Code: Select all | Expand
REQUEST DBFCDX
FUNCTION MAIN()
LOCAL nSec, nKey
RDDSETDEFAULT( "DBFCDX" )
IF !FILE( "CORSE.CDX" )
USE CORSE
INDEX ON UPPER( FIELD -> cliente ) TO CORSE
CLOSE
ENDIF
USE CORSE INDEX CORSE
SET ORDER TO 0
nSec = SECONDS()
SET FILTER TO UPPER( FIELD -> cliente ) = "A"
nKey = ORDKEYCOUNT()
? SECONDS() - nSec, nKey
CLOSE
RETURN NIL
As you can see, the only required change is SET ORDER TO 0.
EMG
- Enrico Maria Giordano
- Posts: 8769
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Has thanked: 1 time
- Been thanked: 6 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
I would explain that my new sample is as fast as your. So nothing related to optimizations. 
EMG

EMG
- nageswaragunupudi
- Posts: 10733
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Been thanked: 10 times
- Contact:
Re: Advice needed for reccount() in scopped and filtered dbfcdx.
Mr EMG
You modified my code.
For once please compile my code exactly as it is without changing even a single alphabet and then see the difference. I guarantee a difference in speed.
BTW may I know the total number of records?
Or please send me your dbf ziipped.
You modified my code.
For once please compile my code exactly as it is without changing even a single alphabet and then see the difference. I guarantee a difference in speed.
BTW may I know the total number of records?
Or please send me your dbf ziipped.
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India