Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
.idx vs .cdx
Message
De
11/06/2005 04:58:44
 
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Base de données, Tables, Vues, Index et syntaxe SQL
Titre:
Versions des environnements
Visual FoxPro:
VFP 6 SP5
Database:
Visual FoxPro
Divers
Thread ID:
01014169
Message ID:
01022421
Vues:
19
Hi Sergey,

(had some hectic days - sorry for the delay) I've cleaned up the test a bit and given it a parameterized signature for the most important settings. The calls here should be fast enough to run quickly on any system, but check if you have disks "on" the drive letters. Be sure to set test run characteristics for your system and/or typical scenario with number of records and distribution of seeks vs. other operations. The wait wind in between is to make sure the system doesn't overheat and slow down because of that: one of the laptops was having problems during longer runs.

Since I have programs running for hours and sometimes days I set the numbers for high class machines, very fast disk and large tables - these are the runs *I* want to optimize further. Be sure to test a spectrum.

regards

thomas
CLEAR
= idxtstRun()
= idxtstRun(0200, 10, 050, "C:")
= idxtstRun(1000, 02, 500, "F:", "D:")

FUNCTION idxtstrun
PARAMETERS tnSeekCountDiv10, tnRecCntFactor, tnNoBoolIdx, tcOptDefDir, tcOptIdxDir, tlOptUseCursor
* tnSeekCountDiv10 : the number of seeks to be executed div 10 (using an array for older versions).
* tnRecCntFactor : the mutiplier for Parameter 1 to get the number of records to be used.
* tnNoBoolIdx : Logical fields can take some time when measuring idx, 
* therefore a numerical border to skip this measurement can be set in the third parameter. 
* Optional paths 
* tcOptDefDir : switching the directory the test is run in 
* (I've disks with different characteristics here from Ramdisk over SCSI, UDMA, downto laptop disks). 
* tcOptIdxDir : Also you can set the path for the non-structural idx/cdx to another (faster) disk. 
* tlOptUseCursor : You can measure cursor perfomance optionally, default is table.


private pcPersType, pcFldType, pnSqlMany
SET TALK OFF
SET SAFETY OFF
CLOSE DATABASES all
CLOSE TABLES all
_Screen.FontSize = 10
_Screen.FontName = "Arial"
pnSqlMany = 0
tnSeekCountDiv10 = IIF(EMPTY(m.tnSeekCountDiv10), 100, m.tnSeekCountDiv10)
tnRecCntFactor = IIF(EMPTY(m.tnRecCntFactor), 5, m.tnRecCntFactor)
tnNoBoolIdx = IIF(EMPTY(m.tnNoBoolIdx), 5000, m.tnNoBoolIdx)
LOCAL lcOldDir
lcOldDir = SYS(5) + CURDIR()
IF VARTYPE(m.tcDefDir)="C"
	SET DEFAULT TO &tcDefDir
ENDIF
pcPersType = IIF(m.tlOptUseCursor, "Cursor", "Table")
pcFldType = ""
CREATE DATABASE TestIndex

? "FIELDTYPE","COMPACT" AT 30,"IDX" AT 80,"COMPACT" AT 120

lcTitle = "Fill,  ReInd,  Seek,   Updt,  Scan,  Query"
? lcTitle at 15, lcTitle at 60, lcTitle at 105

FOR FLDTYPE= 1 TO 7
	? M.FLDTYPE,SPACE(3)
	=TEST(m.FLDTYPE,.t.),TEST(m.FLDTYPE,.f.),TEST(m.FLDTYPE,.T.)	&& CHECK CACHE EFFECT
	?? " Fieldtype:" + m.pcFldType

NEXT
? "Done with Fill, ReInd, Update, Scan with Records:" + STR(Recmany())  ;
	+ ", No. of Seeks: " + STR(10*m.tnSeekCountDiv10) ;
	+ ", No. of Queries:" + STR(m.pnSqlMany) ;
	+ " With: " +  m.pcPersType ;
	+ " in " + SYS(5) + CURDIR() ;
	+ ", indices in " + Indexfilename("*.?dx") ;
	+ ", vfp:" + VERSION(4)

SET DATABASE TO 
CLOSE DATABASES all
DELETE FILE TestIndex.dbc
DELETE FILE TestIndex.dct
DELETE FILE TestIndex.dcx
IF LEFT(m.pcPersType, 1)="T" 
	DELETE FILE "TestINdex.dbf"
	DELETE FILE "TestINdex.cdx"
endif
DELETE FILE (indexfilename("ONECDX.CDX"))
DELETE FILE (indexfilename("TAGIDX.IDX"))
SET TALK On
SET SAFETY On
SET DEFAULT TO &lcOldDir
?

PROCEDURE TEST(TYPEFIELD,COMPACTINDEX)

local laF[1], laDummy[1], ;
	lcOrder, lcDxFile, ;
	lnTF, lnTR, lnTS, lnTU, lnTM, lnTQ, lnT1

STORE 0 TO lnTF, lnTR, lnTS, lnTU, lnTM, lnTQ
PRIVATE pcKey, ;
	pa0, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9

Dimension ;
	pa0[m.tnSeekCountDiv10], pa1[m.tnSeekCountDiv10], pa2[m.tnSeekCountDiv10], ;
	pa3[m.tnSeekCountDiv10], pa4[m.tnSeekCountDiv10], pa5[m.tnSeekCountDiv10], ;
	pa6[m.tnSeekCountDiv10], pa7[m.tnSeekCountDiv10], pa8[m.tnSeekCountDiv10], ;
	pa9[m.tnSeekCountDiv10]

FOR JJ=0 TO 3
	IF LEFT(m.pcPersType, 1)="T" 
		IF INDBC("TEstIndex","TABLE")
			DROP TABLE TestIndex
		endif
		DELETE FILE "TestINdex.dbf"
		DELETE FILE "TestINdex.cdx"
	endif
	DO CASE
		CASE TYPEFIELD=1
			IF m.tnSeekCountDiv10>tnNoBoolIdx AND !m.COMPACTINDEX
				?? PADC("Skipped", 62) + SPACE(1)
				return
			endif
			CREATE &pcPersType TestIndex (F1 L DEFAULT RAND()>0.5)

		CASE TYPEFIELD=2
			CREATE &pcPersType TestIndex (F1 I DEFAULT RAND()*100000)

		CASE TYPEFIELD=3
			CREATE &pcPersType TestIndex (F1 D DEFAULT DATE()+RAND()*10000)

		CASE TYPEFIELD=4
			CREATE &pcPersType TestIndex (F1 T DEFAULT DATETIME()+RAND()*10000)

		CASE TYPEFIELD=5
			CREATE &pcPersType TestIndex (F1 N(15,8) DEFAULT RAND()*100000)

		CASE TYPEFIELD=6
			CREATE &pcPersType TestIndex (F1 C(20) DEFAULT REPLICATE(CHR(RAND()*256),RAND()*021))

		CASE TYPEFIELD=7 AND VERSION(5)>=900
			CREATE CURSOR TestIndex (F1 V(99) DEFAULT REPLICATE(CHR(RAND()*256),RAND()*100))
		OTHERWISE
			pcFldType = ""
			return
	ENDCASE
	= AFIELDS(laF)
	pcFldType = laF[1,2]

	IF m.COMPACTINDEX
		lcDxFile = indexfilename("ONECDX.CDX")
	*	INDEX ON F1 TAG SCDX
		INDEX ON F1 TAG NCDX OF (m.lcDxFile)
	*	INDEX ON F1 TO TAGIDX.IDX COMPACT && THIS IS USELESS
	ELSE
		lcDxFile = indexfilename("TAGIDX.IDX")
		INDEX ON F1 TO (m.lcDxFile)
	ENDIF
	pcKey = KEY()
	lcOrder = ORDER()

	SET ORDER TO

	lnT1=SECONDS()
	FOR K=1 TO RecMany()
		APPEND BLANK
	NEXT
	lntf=m.lntf+SECONDS()-m.lnt1

	lnT1=SECONDS()
	REINDEX
	lntr=m.lntr+SECONDS()-m.lnt1

	SET ORDER to &lcOrder
	= SeekInit()
	lnT1=SECONDS()
	= SeekTest()
	lnts=m.lnts+SECONDS()-m.lnt1



	SET ORDER TO
	SELECT f1 FROM TestIndex INTO CURSOR dup nofilter
	GO BOTTOM in DUP
	SELECT TestIndex
	lnT1=SECONDS()
	Scan
		replace f1 WITH dup.f1
		SKIP -1 IN DUP
	ENDSCAN
	lntU=m.lntU+SECONDS()-m.lnt1


	SET ORDER TO &lcOrder
	SELECT Dup
	SET RELATION TO F1 INTO TestIndex
	lnT1=SECONDS()
	SCAN
		lux = TestIndex.F1
	ENDSCAN
	lntM=m.lntM+SECONDS()-m.lnt1

	SET RELATION TO 
	lnT1=SECONDS()
	pnSqlMany = 0
	SCAN FOR RECNO()< max(3, RECCOUNT()/1000-10)
		pnSqlMany = m.pnSqlMany + 1
		lu1 = f1
		SKIP 10
		lu2 = f1
		SKIP -10
		luMin = MIN(m.lu1, m.lu2)
		luMax = MAX(m.lu1, m.lu2)
		SELECT * from TestIndex WHERE BETWEEN(&pcKey, m.luMin, m.luMax) INTO Cursor laDummy
	EndScan
	lntQ=m.lntQ+SECONDS()-m.lnt1

	USE
	= CleanBetWeen()
NEXT
?? STR(m.lnTF/m.jj,6,3), ;
	STR(m.lntr/m.jj,6,3), ;
	STR(m.lnts/m.jj,6,3), ;
	STR(m.lntu/m.jj,6,3), ;
	STR(m.lntm/m.jj,6,3), ;
	STR(m.lntq/m.jj,6,3), ;
	SPACE(5)

FUNCTION indexfilename(tcFilename)
RETURN IIF(EMPTY(m.tcOptIdxDir), "", ADDBS(m.tcOptIdxDir)) + m.tcFilename

FUNCTION RecMany
RETURN m.tnRecCntFactor*m.tnSeekCountDiv10

FUNCTION CleanBetween()
	= SYS(1104)
	private lnWait
	lnWait = MIN(MAX(0.1, RecMany()/20000),1)
	WAIT WINDOW "CoolIt" + STR(m.lnWait, 6,2) TimeOut m.lnWait

FUNCTION SeekInit()
private lcKey
lcKey = KEY()
LOCAL lnRun
FOR lnRun = 1 TO m.tnSeekCountDiv10
	pa0[m.lnRun] = SeekFill()
	pa1[m.lnRun] = SeekFill()
	pa2[m.lnRun] = SeekFill()
	pa3[m.lnRun] = SeekFill()
	pa4[m.lnRun] = SeekFill()
	pa5[m.lnRun] = SeekFill()
	pa6[m.lnRun] = SeekFill()
	pa7[m.lnRun] = SeekFill()
	pa8[m.lnRun] = SeekFill()
	pa9[m.lnRun] = SeekFill()
NEXT

FUNCTION SeekFill()
	GO INT(MAX(1, MIN(RECCOUNT(), RAND()*RECCOUNT())))
	RETURN EVALUATE(m.pcKey)

FUNCTION SeekTest
private lnRun 
FOR lnRun = 1 TO m.tnSeekCountDiv10
	= SEEK(pa0[m.lnRun])
	= SEEK(pa1[m.lnRun])
	= SEEK(pa2[m.lnRun])
	= SEEK(pa3[m.lnRun])
	= SEEK(pa4[m.lnRun])
	= SEEK(pa5[m.lnRun])
	= SEEK(pa6[m.lnRun])
	= SEEK(pa7[m.lnRun])
	= SEEK(pa8[m.lnRun])
	= SEEK(pa9[m.lnRun])
NEXT
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform