KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q275515: PRB: Performance Degradation with SQL Selects from Offline Views

Article: Q275515
Product(s): Microsoft FoxPro
Version(s): 5.0,5.0a,6.0
Operating System(s): 
Keyword(s): kbDatabase kbvfp500 kbvfp500a kbvfp600 KbDBFDBC kbGrpDSFox kbDSupport kbCodeSnippet
Last Modified: 24-OCT-2000

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Visual FoxPro for Windows, versions 5.0, 5.0a, 6.0 
-------------------------------------------------------------------------------

SYMPTOMS
========

When you issue SQL SELECT statements against offline views, the performance of
an application degrades, and system resources are gradually depleted.

RESOLUTION
==========

Issue SQL SELECT statements against online views or tables rather than offline
views.

MORE INFORMATION
================

Steps to Reproduce Behavior
---------------------------

1. Create a program file named "Memdemo.prg" and paste the following code:

  IF !FILE("MYOLV.DBC")
     SET SAFETY OFF
     SET MULTILOCKS ON
     * Create a database.
     CREATE DATABASE MYOLV
     * Declare API function to create ODBC DSN.
     DECLARE INTEGER SQLConfigDataSource IN odbccp32.DLL ;
        INTEGER, INTEGER, STRING, STRING
     IF VAL(SUBSTR(VERSION(),15,2))=6 OR VAL(SUBSTR(VERSION(),15,2))=7
        lcDir=HOME(2)+"data\"
     ELSE
        lcDir=HOME()+"SAMPLES\DATA\"
     ENDIF
     * Information to setup ODBC DSN.
     lcSetUp="DSN=MyOffLine"+CHR(0)+;
        "Description=VFP Offline View Demo"+CHR(0)+;
        "SourceDB="+lcDir+"testdata.dbc"+CHR(0)+;
        "SourceType=DBC"
     * Call API function to create a DSN.
     =SQLConfigDataSource(0,1,"Microsoft Visual FoxPro Driver",lcSetUp)
     CLEAR DLLS
     * Create a connection.
     CREATE CONNECTION MYOLV DATASOURCE "myoffline"
     * Create a view to take offline.
     CREATE SQL VIEW test REMOTE CONNECT MYOLV ;
        AS SELECT cust_id, company, city ;
        FROM customer ;
        ORDER BY customer.cust_id
     USE test
     * Take the view offline.
     * Creates file named 'Test.dbf'.
     =CREATEOFFLINE('test')
     * Close all and open the Table for OffLine view.
     CLOSE ALL
  ENDIF

  CLOSE ALL
  CLEAR ALL
  OPEN DATABASE MYOLV
  SET MULTILOCKS ON
  * Get the value of User Object Memory.
  startval=VAL(SYS(1016))
  * Get the value of Memory Handles.
  startsysval=VAL(SYS(1011))
  FOR i=1 TO 10000
     * Issue a SQL Select statement against an Offline View.
     SELECT * FROM test INTO CURSOR testing
     * Get the current value of User Object Memory.
     endval=VAL(SYS(1016))
     * Get the current value of Memory Handles.
     endsysval=VAL(SYS(1011))
     * Check the amount of available physical memory.
     memcheck(endval-startval,endsysval-startsysval)
     startval=endval
     startsysval=endsysval
     WAIT WINDOW "Iteration = " + ALLTRIM(STR(i)) NOWA
  ENDFOR
  CLOSE ALL

  *******************************************************************
  PROCEDURE memcheck
  *******************************************************************
     LPARAMETERS userobj, usedhandles
     lcCurrent=ALIAS()
     * Check for existence of memvals.dbf to store memory values.
     IF !FILE('memvals.dbf')
        SELECT 0
        CREATE TABLE memvals FREE (availphys N(15,0), fox_mem c(15), usermem i, memhandles i, when_fire T)
        USE IN memvals
     ENDIF
     * Declare GlobalMemoryStatus API.
     DECLARE GlobalMemoryStatus IN Win32API STRING @MemStat
     m.struc = long2str(32) + REPLICATE(CHR(0), 28)
     * Call GlobalMemoryStatus.
     =GlobalMemoryStatus(@m.struc)
     * Get Available Physical Memory.
     m.availphys = str2long(SUBSTR(m.struc, 13, 4))
     INSERT INTO memvals VALUES (m.availphys, SYS(1001), userobj, usedhandles, DATETIME())
     USE IN memvals
     IF !EMPTY(lcCurrent)
        SELECT (lcCurrent)
     ENDIF
     CLEAR DLLS
     RETURN

  *******************************************************************
  FUNCTION long2str
  *******************************************************************
     PARAMETERS m.longval
     PRIVATE i, m.retstr
     m.retstr = ""
     FOR i = 24 TO 0 STEP -8
        m.retstr = CHR(INT(m.longval/(2^i))) + m.retstr
        m.longval = MOD(m.longval, (2^i))
     NEXT
     RETURN m.retstr

  *******************************************************************
  FUNCTION str2long
  *******************************************************************
     PARAMETERS m.longstr
     PRIVATE i, m.retval
     m.retval = 0
     FOR i = 0 TO 24 STEP 8
        m.retval = m.retval + (ASC(m.longstr) * (2^i))
        m.longstr = RIGHT(m.longstr, LEN(m.longstr) - 1)
     NEXT
     RETURN m.retval

2. Save and then run the program file.

3. Open and BROWSE the memvals table. Inspect the values that are stored in the
  table. Note that the availphys column shows a downward trend.

4. From the Command window, run the following code:

  SELECT AVG(availphys) AS availphys FROM memvals WHERE RECNO()<=30 INTO CURSOR baseline
  SELECT AVG(availphys) AS availphys FROM MEMVALS WHERE RECNO()>=RECCOUNT()-30 INTO CURSOR endline
  ? baseline.availphys-endline.availphys

REFERENCES
==========

(c) Microsoft Corporation 2000, All Rights Reserved. Contributions by John
Desch, Microsoft Corporation.


Additional query words: Offline View SQL Select

======================================================================
Keywords          : kbDatabase kbvfp500 kbvfp500a kbvfp600 KbDBFDBC kbGrpDSFox kbDSupport kbCodeSnippet 
Technology        : kbVFPsearch kbAudDeveloper kbVFP500 kbVFP600 kbVFP500a
Version           : :5.0,5.0a,6.0
Issue type        : kbprb
Solution Type     : kbnofix

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.