2013-03-25 63 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