2013-03-25 109 views
0

我有以下查询在我的Access 2003数据库:SQL Access查询速度

SELECT 
    Projet.OTP AS OTP, 
    NumeroDA, 
    SUM(Quantite*PrixReelCommande) AS PrixTotal, 
    FIRST(Fournisseur1) AS Fournisseur, 
    FIRST(Projet.NumeroCommandeReservation) AS NumeroCommande, 
    FIRST(Projet.GestionContrat) AS GestionContrat, 
    FIRST(Projet.Acheteur) AS Acheteur, 
    MIN(DateLivraisonContractuelle) AS DateLivraisonContrat, 
    MAX(DateFournisseurLivraison) AS DateLivraisonFournisseur, 
    FIRST(InfoProjet.NomInstallation) AS NomInstallation, 
    FIRST(InfoProjet.TitreMandat) AS TitreMandat 
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP 
WHERE NumeroDA Like "#*" And NumeroDA IN (
              SELECT NumeroDA FROM Projet 
              WHERE NumeroCommandeReservation="" Or NumeroCommandeReservation Is Null Or NumeroCommandeReservation="0" 
             ) 
GROUP BY Projet.OTP, Projet.NumeroDA 
ORDER BY Projet.OTP, Projet.NumeroDA 

表谟有〜2500行和InfoProjet只有200行。在Access中打开这个表格不到1秒。但是,执行上述查询需要超过5秒钟。

我想知道是否有任何事情可以改善此查询的性能。查询中是否有某些内容我应该避免使用性能?或者我只是在访问限制下?我猜在子查询中使用Like没有帮助,但是肯定还有其他的东西会降低查询速度。

+0

你对(OTP)指数双双表上?如果是这样,索引是否包括列NumeroDA。你有NumeroCommandeReservation索引,还包括NumeroDA? – ljh 2013-03-25 17:07:12

+0

OTP上没有索引,有多个具有相同OTP的行。但是我们可以在Access中设置非唯一索引,您认为这对于这种情况会有帮助吗? NumeroDA相同,有多行具有相同的NumeraDA和NumeroCommandeReservation。这些PK是NumeroListe和NumeroArticle,都以重复支持为索引。 – dnLL 2013-03-25 17:12:16

+1

它不必是唯一的,非唯一索引也可以帮助查询,如果可以创建复合索引或覆盖索引,它可以帮助更多。 – ljh 2013-03-25 17:15:31

回答

1

由于您没有在子查询中使用任何Distinct,您是否可以通过将该部分取出来简化它? (我不能现在虽然测试这个权利,所以我不能完全肯定它会给出同样的结果)

SELECT 
    Projet.OTP AS OTP, 
    NumeroDA, 
    SUM(Quantite*PrixReelCommande) AS PrixTotal, 
    FIRST(Fournisseur1) AS Fournisseur, 
    FIRST(Projet.NumeroCommandeReservation) AS NumeroCommande, 
    FIRST(Projet.GestionContrat) AS GestionContrat, 
    FIRST(Projet.Acheteur) AS Acheteur, 
    MIN(DateLivraisonContractuelle) AS DateLivraisonContrat, 
    MAX(DateFournisseurLivraison) AS DateLivraisonFournisseur, 
    FIRST(InfoProjet.NomInstallation) AS NomInstallation, 
    FIRST(InfoProjet.TitreMandat) AS TitreMandat 
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP 
WHERE NumeroDA Like "#*" And (
    NumeroCommandeReservation="" Or 
    NumeroCommandeReservation Is Null Or 
    NumeroCommandeReservation="0") 

GROUP BY Projet.OTP, Projet.NumeroDA 
ORDER BY Projet.OTP, Projet.NumeroDA 
+0

它确实有效,并在不到一秒的时间内为我提供了相同的结果。所以问题是具有'IN()'函数的子查询。看起来像Access不喜欢它。我会接受你的答案,因为它解决了我的问题,现在我会更加小心。这个查询可能仍然可以改进。 – dnLL 2013-03-25 17:15:02

+0

为了改进查询,这些First()声明让我有点紧张。他们可能隐藏了重要的东西。我建议摆脱这些'First()'语句,而是将这些字段放在Group By语句中。合理? – PowerUser 2013-03-25 21:54:38

0

尝试运行这个,看看它有多少行返回:

SELECT COUNT(*) 
FROM Projet LEFT JOIN InfoProjet ON Projet.OTP=InfoProjet.OTP 
WHERE NumeroDA Like "#*" And NumeroDA IN (
             SELECT NumeroDA FROM Projet 
             WHERE NumeroCommandeReservation="" 
             Or NumeroCommandeReservation Is Null 
             Or NumeroCommandeReservation="0" 
            ) 

原因:加入可返回,你会期望更多的行,但你只有MAX/MIN/FIRST骨料你可能不会注意到。

+0

原始查询只返回23行,这没关系。我只是尝试了你的查询,这与我的原始查询一样长,并且它返回的计数为111. – dnLL 2013-03-25 17:09:33

+0

@dnLL在这种情况下,我认为唯一可以帮助的事情是添加索引作为ljh建议或重写查询删除子查询并将其移动到联接或where部分。 – bendataclear 2013-03-25 17:16:09

+0

PowerUser的解决方案实际上解决了我的问题,但我也会考虑添加索引。 – dnLL 2013-03-25 17:27:32