nageswaragunupudi wrote:We can discuss that later if and when you need.
As Nages said, it all depends on what is inside the DBF. Imagine a 100.000 records dbf, with only 2 records deleted. There should be absolutely no difference between the various methods described in terms of refresh time. If you start to have 10% of records deleted it may make a difference.
SET DELETED ON:
When you only use SET DELETED ON, as previously noticed, all the records are read from the dbf, analyzed and eventually discarded. Almost all browse systems use dbSkip() to move between records. So if you need to display record 150 and the next not deleted record is 850, 600 records are read, checked, discarded. Since DBFs can be shared and someone else may modify the data (unless in exclusive mode) the browse systems can't cache which record are displayed so in case of a dbSkip(-1) it has to transfer, check, discard again that 600 records.
Imagine the worst case, in which just record 1 and record 100000 are active.... the browse must read 999998 records...
INDEX ON ! DELETED():
with this index the records are logically divided in two groups, the active and the deleted. Now record 150 and record 850 are 1 record from each other... so dbSkip() is really quick. Imagine the worst case: there are 2 groups, one composed by 2 active records, the other by 999998 records.
Up to here I completely agree with Nages.
What I don't agree is when he adds SET FILTER TO ! deleted() when the index is active.
I did some tests and with INDEX+SET FILTER active, ordKeyCount() doesn't change: it always reports 100.000, because there are 100.000 records in the index.
It may be that the RDD can be quicker reading the deleted() value from the index, but I'm not sure it really does it.
Only ordScope() actually creates a filter using the index. And it can be proved by test small test I write here.
It may be that xBrowse is smart: it may recognize that a filter condition is also present in a index and uses it to set an ordScope() range. In this way ordKeyCount() returns the number of active records present in the DBF.
There is still another way to handle these cases, but it is a bit more complex: custom indexes.
- Code: Select all Expand view RUN
#pragma -w0
procedure main
? "Create DBF"
a := {}
aAdd( a, {"TEST","C",30,0} )
dbCreate( "TEST", a )
USE TEST
FOR i := 1 TO 100000
append blank
NEXT
GO 300
delete
GO 700
delete
go 10000
delete
? "CREATE INDEX"
INDEX ON DELETED() TO TEST
ClOSE DATABASES
? "START TEST"
USE TEST
? "1:", ordKeyCount()
SET FILTER TO !DELETED()
? "2:", ordKeyCount()
SET FILTER TO
SET INDEX TO TEST
? "3:", ordKeyCount()
SET FILTER TO !DELETED()
? "4:", ordKeyCount()
SET FILTER TO
#include "Ord.ch"
OrdScope( TOPSCOPE , .T. )
OrdScope( BOTTOMSCOPE, .T. )
? "5:", ordKeyCount()