2017-09-19 4 views
-1

SQLへの移行の前に2つのサブフォームを持つ単一のフォームがあります。私のフォームのレコードソースは、クエリが高速に実行されています。それは1秒だった前 は今、私はこのフォームでフィルタリングレコードの検索ボタンをクリックすると、3分sqlに移行した後、フォームの検索がAccessフロントエンドでゆっくり実行されています

  DoCmd.OpenForm "frmDocuments", WhereCondition:=varWhere 

後に非常にゆっくりと実行されます。

Private Sub cmdSearch_Click() 
    Dim varWhere As Variant, varWhere2 As Variant, varDateSearch As Variant 
Dim rst As DAO.Recordset 

' Initialize to Null 
    varWhere = Null 
    varWhere2 = Null 
    varDateSearch = Null 
If Not IsNothing(Me.txtTransmittal_to_Site) Then 
    ' .. build the predicate 
    ' Must use a subquery here because the value is in a linking table... 
    varWhere = (varWhere + " AND ") & _ 
     "[Owner Document Number] IN (SELECT [Owner Document Number] FROM tblTransmittals " & _ 
     "WHERE tblTransmittals.[CT- Transmittals] LIKE '" & Me.txtTransmittal_to_Site & "*')" 
End If 
    If IsNothing(varWhere) Then 
    MsgBox "You must enter at least one search criteria.", vbInformation, gstrAppTitle 
    Exit Sub 
End If 

' Open a recordset to see if any rows returned with this filter 
Set rst = DBEngine(0)(0).OpenRecordset("SELECT * FROM tblDocuments WHERE " & varWhere) 
' See if found none 
If rst.RecordCount = 0 Then 
    MsgBox "No Documents meet your criteria.", vbInformation, gstrAppTitle 
    ' Clean up recordset 
    rst.Close 
    Set rst = Nothing 
    Exit Sub 
End If 

' Hide me to fix later focus problems 
Me.Visible = False 
' Move to last to find out how many 
rst.MoveLast 

    varWhere3 = Replace(varWhere, "*", "%") 

     Set qdf = CurrentDb.CreateQueryDef("") 

    qdf.Connect = "ODBC; DRIVER=SQL SERVER; SERVER=DESKTOP-JL7MJL4; 

    DATABASE=EDMS_BB2_with_relation - Copy (4)SQL; Trusted_Connection=YES;" 

     qdf.SQL = "SELECT tblDocuments.[Owner Document Number], tblDocuments. 
    [Sazeh Document Number], tblDocuments.[Document Title], tblDocuments. 
    [Project No], tblDocuments.Originator, tblOriginator.[Originator Des], 
    tblDocuments.Zone, tblDocuments.Unit, tblDocuments.Discipline, 
    tblDiscipline.DiscDesc, tblDocuments.[Document Type], tblDocumentType. 
    [TYPE Description], tblDocuments.SheetNumber " & _ 
"FROM tblDiscipline RIGHT JOIN ((tblDocumentType RIGHT JOIN tblDocuments ON 
    tblDocumentType.TYPE = tblDocuments.[Document Type]) LEFT JOIN 
    tblOriginator ON tblDocuments.Originator = tblOriginator.Originator) ON 
    tblDiscipline.DiscCode = tblDocuments.Discipline WHERE " & _ 
    varWhere3 & _ 
    " ORDER BY tblDocuments.[Owner Document Number]" 
     qdf.ReturnsRecords = True 
     Set rst2 = qdf.OpenRecordset 


If IsFormLoaded("frmDocuments") Then 
    DoCmd.OpenForm "frmDocuments", acNormal 
    Set Forms!frmDocuments.Recordset = rst2 

    Forms!frmDocuments.SetFocus 

End If 

答えて

1

まず、完全なクエリを実行してレコードがあるかどうかをユーザーに伝えます。そのためにすべてのレコードを返す必要はありません。同じ理由でSELECT TOP 1 ...

のような検索クエリを制限し、すべての列を返す必要がない、あなただけはSQLバックエンドに移動しているにもかかわらず、SELECT TOP 1 [Owner Document Number] ...

のような単一のフィールドを指定するので、私は情報から想定あなたがリンクされたテーブルを使用しているという質問の中で。 Accessデータベースエンジンは特にインテリジェントではないので、おそらくサブクエリを別々に実行し、メインクエリのすべてのレコードのサブクエリを検索し、そのサブクエリのデータがインデックスに登録されないことがあります。メインクエリ内のすべての個別の行に対してサブクエリを実行している場合もあります。これをより効率的にするためにできることがいくつかあります。 JOINを使用します。そのため、索引を使用して問合せをより効率的にする可能性が高くなります。何かのように

SELECT TOP 1 Docs.[Owner Document Number] 
FROM tblDocuments AS Docs INNER JOIN tblTransmittals AS Tmls 
    ON Docs.[Owner Document Number] = Tmls.[Owner Document Number] 
WHERE Tmls.[CT- Transmittals] LIKE 'foobar*' 

それを正しくまとめるまでです。

最後に(実際にはカップルのコメントはまだありませんが驚いています)、ユーザーのデータを決してSQLステートメントに挿入しないでください。常にパラメータ化されたクエリを使用します。 Accessでは、パラメータ付きのQueryDefを作成することを意味します。 db.CreateQueryDef("", SQL)

これらのヒントではパフォーマンスが十分に向上しない場合は、最初のレコードチェックのためにSQLサーバーに直接パススルークエリを送信することを検討してください。 DoCmd.OpenFormにWHERE条件を送信するのではなく、最適化されたクエリでForm.RecordSourceをリセットすることも検討してください。これらの手法はどちらも個別に研究することができ、そのような詳細はこの質問の範囲外です。

+0

私のフォームのレコードソースは、すべてのレコードを返すパススルークエリです。 VBAでは、この事前定義されたクエリにForm.RecordSourceを定義し、where clouseを追加することができます。 – Masoud

+0

明確にするために、現在のForm.RecordSourceはパススルークエリである_saved_クエリ(つまりQueryDef)に設定されていますか? –

+0

[この質問](https://stackoverflow.com/questions/38620119/using-a-stored-procedure-as-a-ms-access-form-recordsource)への答えには、これを達成する唯一の方法ではありませんが、フォームのQueryDefを介して。 –

関連する問題