优化 MS Access 双子查询

Optimize MS Access Double SubQuery

我正在构建的这个 MS Access 查询非常慢。我只测试一个月的数据(一个 table 驱动此查询有 28,577 条记录,36 列)。

这是我想要完成的:

我想 return 在特定交易类型中按型号销售的独特车辆的数量(此数据库未规范化,并且是根据 excel sheet 加载的变成 table)。

存在第一个子查询是因为据我所知,在 Access 中您不能将 DISTINCT 语句与聚合函数一起使用。所以我需要构建一个子查询来处理 Count(DISTINCT VIN)。

我认为第二个子查询是罪魁祸首。每个 VIN 可能有很多条目。例如,车辆可能已使用我正在计算的交易类别之一售出,然后被取消,并转售到我不想计算的交易类别之一。这将为此 VIN 生成三个记录:

  1. 销售到我认为我想统计的交易类别
  2. 取消第一次销售
  3. 转售成我不想算的交易类别

第二个子查询检查 VIN 是否有 "cancelled Sale" 记录,然后不将第一个 Sale 计入计数。

希望我解释得很好,有人可以为我提供一个可能的解决方案来加速这个查询。

谢谢

查询

PARAMETERS [Enter Sales Month Start Date] DATETIME, [Enter Sales Month End Date] 
DATETIME; 

SELECT DSTNCT_COUNT.trans      AS Trans, 
       DSTNCT_COUNT.mdl        AS Model, 
       Count(DSTNCT_COUNT.cnt) AS VIN_COUNT 
FROM   (SELECT DISTINCT new_bbss.vin              AS cNt, 
                        new_bbss.[model category] AS MDL, 
                        new_bbss.[trans category] AS Trans 
        FROM   new_bbss 
        WHERE  ( ( ( new_bbss.[trans category] ) NOT LIKE 'Individual' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Corporate' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Cancel' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Partners' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Special' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Employee' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'Mobile' 
                   AND ( new_bbss.[trans category] ) NOT LIKE 'JLR FLEET' ) 
                   AND ( ( new_bbss.[retailer code] ) LIKE 'R*' ) ) 
                   AND new_bbss.[trans date] BETWEEN [enter sales month start date] 
                                             AND 
                                                 [enter sales month end date] 
                   AND new_bbss.vin NOT IN(SELECT new_bbss.vin 
                                           FROM   new_bbss 
                                           WHERE  new_bbss.[trans category] LIKE 
                                              'CancelVIP*' 
                                               OR new_bbss.[trans category] LIKE 
                                                  'CancelDealer Local*' 
                                               OR new_bbss.[trans category] LIKE 
                                                  'CancelLoaner*' 
                                               OR new_bbss.[trans category] LIKE 
                                                  'CancelAlive*'))
       AS DSTNCT_COUNT 
GROUP  BY trans, mdl; 

Ms​​Access 在 NOT IN 上应该比在 NOT EXISTS 上慢。我不知道这是不是真的,但你可以试试。此外,您可以将此限制从 WHERE 子句移至 HAVING 子句,因为 vin 在 GROUP BY 子句中。这可能会减少 MsAccess 必须查找的次数。

select [model category], [trans category], count(*)
from
(
  select [model category], [trans category], vin
  from new_bbss
  where [trans category] not like 'Individual' 
    and [trans category] not like 'Corporate' 
    and [trans category] not like 'Cancel' 
    and [trans category] not like 'Partners' 
    and [trans category] not like 'Special' 
    and [trans category] not like 'Employee' 
    and [trans category] not like 'Mobile' 
    and [trans category] not like 'JLR FLEET' 
    and [retailer code] like 'R*'
    and [trans date] between [enter sales month start date] 
                         and [enter sales month end date] 
  group by [model category], [trans category], vin
  having not exists
  (
    select *
    from new_bbss unwanted
    where unwanted.vin = new_bbss.vin
    and  
    (    unwanted.[trans category] like 'CancelVIP*' 
      or unwanted.[trans category] like 'CancelDealer Local*' 
      or unwanted.[trans category] like 'CancelLoaner*' 
      or unwanted.[trans category] like 'CancelAlive*'
    )
  )
) matches
group by [model category], [trans category];

顺便说一句:vin 上应该有一个索引,这样MsAccess 可以快速查找它的记录。