你会如何优化这个查询

How would you optimize this query

我在 VFP9(是的,我知道)下一个查询完美运行,但是使用大小为 20mb(或 9k 行)的 DBF(Table)在游标上创建临时大于 2gb 的文件(这会使 VFP9 崩溃,因为它是 32 位)

            SELECT DISTINCT t1.*;
            FROM t1,t2;
            WHERE ALLTRIM(t1.name) = ALLTRIM(t2.name);
            AND ALLTRIM(t1.name2) = ALLTRIM(t2.name2);
            AND t1.tyc = t2.tyc;
            AND t1.nc = t2.nc;
            AND t1.forced = 0;
            AND t1.secuence NOT in (Select secuence FROM t2);   
            Into Cursor cursordel

我只放这段代码是因为行得通,除非我有超过 2k 行 我认为用连接替换“不在”可以解决问题,但没有奏效,或者至少我尝试过的方式没有奏效...

这看起来你可以做一个内部连接,我不知道 fox pro 如何处理游标中的交叉连接听起来交叉连接在这里造成了损害:9,000 行在 20mb 未修剪的交叉连接远远超过 2 GB,但听起来这可能有帮助:

SELECT;
        DISTINCT t1.*;
        FROM t1; 
        inner join t2 on
        ALLTRIM(t1.name) = ALLTRIM(t2.name)
        AND ALLTRIM(t1.name2) = ALLTRIM(t2.name2)
        AND t1.tyc = t2.tyc
        AND t1.nc = t2.nc
        AND t1.forced = 0
        AND t1.secuence NOT in (Select secuence FROM t2)
        Into Cursor cursordel

假设第一个 table 没有重复项,我会将其表述为 not exists:

SELECT t1.*
FROM t1
WHERE NOT EXISTS (SELECT 1
                  FROM t2
                  WHERE ALLTRIM(t1.name) = ALLTRIM(t2.name) AND
                        ALLTRIM(t1.name2) = ALLTRIM(t2.name2) AND
                        t1.tyc = t2.tyc AND
                        t1.nc = t2.nc
                ) AND
      t1.forced = 0 AND
      NOT EXISTS (SELECT 1
                  FROM t2
                  WHERE t2.secuence = t1.secuence
                 );  

然后对于此查询,您需要 t2(tyc, nc, name, name2)t2(secuence) 上的索引。我怀疑 t1(forced) 上的索引是否有帮助,除非该列很少 0.

即使没有索引,这也消除了外部 SELECT DISTINCT

请注意,您在 t2 上的 NOT IN 情况看起来很可疑。为什么它也不需要匹配条件?

为什么首先需要 distinct?当您只想执行 EXISTS 检查时,为什么要创建隐式交叉连接然后进行过滤?而且,那些 alltrim() 的目的是什么?您的字段是否有前导空格?还是您的意思是 trim 尾随空格?如果是后者,则完全没有必要,并且还会阻止使用可能存在的索引。

SELECT * ;
            FROM t1 ;
            WHERE t1.forced = 0 ; 
            and EXISTS (select * from t2 ;
              where t1.name == t2.name ;
                AND t1.name2  == t2.name2 ;
                AND t1.tyc == t2.tyc ;
                AND t1.nc == t2.nc ) ;
            and not EXISTS (select * from t2 where t1.secuence = t2.secuence) ;
            Into Cursor cursordel ;
            NOFILTER