sqlt-sqlquery-optimizationvisual-foxprocommand-window

vfp query much faster in command window than compiled


Here's my query:

SELECT solGroup,;
       SUM(IIF((;
                SELECT COUNT(*) FROM cgift c2;
                    WHERE c2.solgroup != c1.solgroup AND c1.donor == c2.donor;
                ) > 0;
           ,1,0));
        countgaveother;
    FROM cgift c1;
    GROUP BY solGroup

cGift is a cursor containing a list of records.

autonumber...donor....solGroup
1............10.......a
2............11.......a
3............10.......b
4............15.......b
5............10.......c
6............15.......c
7............11.......d
8............11.......d
9............16.......d

The query generates the following

solGroup.."count of donors who have records with a different solgroup as well as this one"
a..........2
b..........2
c..........2
d..........1

There are about 80k records in cGift (and many more fields that are not used here). It takes 3 seconds to run this query (plus the one creating the cursor) from the vfp command window and 30 minutes to run from inside a compiled form.

Anyone have any idea why the performance difference is so great? Normally the command window performs very similar to my compiled forms. Other queries run perfectly fine in this form as well.

The cursor is created with a select ... into cursor cGift. It is ordered by donor, though removing this changes nothing.

I'm on VFP 9 sp2. Anyone know how speed it up?

EDIT: Ok, let me summarize and see if anyone else has any ideas.
I create a cursor with a select into ... cursor cGift.
Then I run the above query on said cursor.
It's fast in the command window but very slow when running from a form.
Exact same code for both cursor and query.
I have no idea what environment settings are on/off/wtvr in my form since it's part of a very large program.


Solution

  • ok, i couldn't figure out what was different in the two enviorments but i sped the query up by changing it and breaking into two parts (something is wrong the with the sql engine if queries run faster after being broken apart...)

    SELECT *;
        FROM cgift;
        LEFT JOIN;
             (select donor donor2, count(distinct solgroup) activesols from cGift group by donor);
        b ON cgift.donor = b.donor2 INTO CURSOR cgift
    

    Then i count where activesol > 1

    Merging those makes everything very slow.