perf(fivesql2): gate VIEW temp cleanup on actual view usage
After the SELECT WA cache landed, pprof showed HbFileExists → os.Stat at 28% of remaining CPU — the RunSelect cleanup loop was stat-ing __view_<table>.dbf for every table in every query, even on the common view-free path. Track view materialisation with a TSqlIndex.lViewUsed flag set in OpenTable when CheckView produces a temp. The cleanup loop now runs only when the flag is set, then resets it. View-using queries are unaffected. pprof delta: rawsyscalln: 2.14s → 1.41s (48% → 32% of total CPU) os.Stat: 1.24s → 0.49s (28% → 11%) Wall-clock bench numbers stayed within plus-or-minus 3% noise (stats are cheap when the target file does not exist, so CPU savings do not translate directly to end-to-end time) but this removes the next biggest syscall waste visible in the profile. FiveSql2 43/43, Harbour compat 56/56. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1662,12 +1662,17 @@ METHOD RunSelect() CLASS TSqlExecutor
|
||||
ENDIF
|
||||
|
||||
/* Clean up VIEW temp files — created by TSqlIndex:CheckView when
|
||||
* a query references a .fsv view. Not tracked elsewhere. */
|
||||
FOR i := 1 TO Len( ::aTables )
|
||||
IF hb_FileExists( "__view_" + Lower( ::aTables[ i ][ 1 ] ) + ".dbf" )
|
||||
FErase( "__view_" + Lower( ::aTables[ i ][ 1 ] ) + ".dbf" )
|
||||
ENDIF
|
||||
NEXT
|
||||
* a query references a .fsv view. The flag lets us skip the stat
|
||||
* loop on view-free queries, which the profile showed as ~28% of
|
||||
* SELECT CPU after the WA cache killed the munmap cost. */
|
||||
IF ::oIndex:lViewUsed
|
||||
FOR i := 1 TO Len( ::aTables )
|
||||
IF hb_FileExists( "__view_" + Lower( ::aTables[ i ][ 1 ] ) + ".dbf" )
|
||||
FErase( "__view_" + Lower( ::aTables[ i ][ 1 ] ) + ".dbf" )
|
||||
ENDIF
|
||||
NEXT
|
||||
::oIndex:lViewUsed := .F.
|
||||
ENDIF
|
||||
|
||||
::nDepth--
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
CLASS TSqlIndex
|
||||
|
||||
/* Set to .T. when CheckView materialises a __view_* temp for a
|
||||
* table this query references — lets RunSelect skip its stat+
|
||||
* FErase cleanup loop on view-free queries (the common case). */
|
||||
DATA lViewUsed INIT .F.
|
||||
|
||||
METHOD New() CONSTRUCTOR
|
||||
METHOD DetectRDD( nWA )
|
||||
METHOD OpenTable( cTable, cAlias, lShared, lReadOnly )
|
||||
@@ -82,6 +87,7 @@ METHOD OpenTable( cTable, cAlias, lShared, lReadOnly ) CLASS TSqlIndex
|
||||
cViewTmp := ::CheckView( cTable )
|
||||
IF ! Empty( cViewTmp )
|
||||
cFileLow := cViewTmp
|
||||
::lViewUsed := .T.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
|
||||
Reference in New Issue
Block a user