2017-04-20 22 views
0

速度問題:MSアクセス - 私はかなり遅いクエリを持って

http://allenbrowne.com/func-concat.html

これは完璧に動作します - しかし、それは本当に遅いです:

SELECT ticketnumber, stateactual, adj, 
    ConcatRelated("utilityname","IntTable","ticketnumber = """ & ticketnumber & """" & " AND " & "stateactual = """ & stateactual & """") AS utilities, 
    ConcatRelated("startupcustomer","IntTable","ticketnumber = """ & ticketnumber & """" & " AND " & "stateactual = """ & stateactual & """") as startdates 
INTO tixconcat 
FROM IntTable 
WHERE stateactual = "MT" 
GROUP BY ticketnumber, stateactual, adj; 

私はこのゲントのconcatrelatedクエリを使用。 1秒に1つのレコード私は110万レコードでこれを実行しようとしており、次回の選挙の前にいつか実行する必要があります。何か案は?

私は既にデータベースを圧縮し修復しました。

ありがとうございます!

+0

デノーマライズデータには欠点があります。あなたのデータはローカルコンピュータ上にありますか、ネットワーク経由でサーバにアクセスしていますか?ローカルデータの方が少し速いかもしれませんが、十分ではないかと思います。 – June7

+0

ConcatRelatedはスピードの問題の主な原因であるUDF(ユーザー定義関数)のように見えます。 UDFは実際にデータを変換する柔軟な方法ですが、数十万行または数百万行のクエリでそれらを使用すると、常に遅くなります。 – Sorcefyre

+0

[ticketnumber]フィールドと[stateactual]フィールドに[IntTable]テーブルのインデックスがありますか? –

答えて

0

時間を要するのは、ConcatRelated関数です。テーブルを開いて検索し、結果を与えた後、テーブルを行ごとに2回閉じる。このプロセスを高速化したい場合は、ユーザー定義関数の代わりにSQLを使用してデータを非正規化する必要があります。

フィールドを連結するには、これを高速化するために使用するプロセスです。

ステップ1 クロス集計クエリを使用して、1行に連結するフィールドを取得します。行見出しとしてあなたの外部キーを使用して、事はあなたがクロス集計クエリ

ステップ3メイクから連結する両方の列見出しと値として

ステップ2 を連結列を連結したいですあなたの最終的なクエリとステップ2からのクエリのクエリ/結果を結合する

5つのクエリ(1つの連結フィールドにつき1つずつ)を使用する必要があります今。 ConcatRelatedは二度同じ値をCONCATすることができますので、あなたはすでに、ステップ1

結果は多少異なる場合がありますでフィルタリングすることができますことに注意してください、と私のアプローチ意志ではないフィールドをインデックス示唆のコメントで

+0

私は従います。私は1100の外部キーを持っています。最終製品の列には十数点以上はありません。あなたはそれが多くの列で動作すると思いますか?私は私のアプローチを完全に再考しなければならないかもしれません。 –

1

一人。それはうまくいった - クエリ全体を1時間で実行した:

0

他の人が指摘したように、それは各行(それは高価です)のような多くの関数を呼び出すことはありません。ただし、SQL文字列をロードし、クエリプロセッサをロードし、SQL構文をチェックしてから、そのクエリプランを作成してから、テーブルを開き、次にコストがどこにあるかをクエリを実行します。

私はクエリプロセッサを渡して、クエリの開始時にテーブルを "一度"直接開くことをお勧めします。したがって、これはインデックスが直接打ち出され、sqlをバイパスするので、seek()コマンドを使用することを意味します。

このコードは約1000倍高速に実行する必要があります。「静的」の使用上記に

Public Function MyCon(vPK As Variant) As String 

    Static rst As DAO.Recordset 
    Static db As DAO.Database 
    Dim strV As String 
    Dim bolF As Boolean 
    'Stop 
    If rst Is Nothing Then 
    Set db = CurrentDb 
    Set rst = db.OpenRecordset("tblChild") 
    End If 

    With rst 
    .Index = "main_id" 
    .MoveFirst 
    .Seek "=", vPK 

    bolF = Not (.NoMatch) 
    Do While bolF 
     If MyCon <> "" Then MyCon = MyCon & "," 
     MyCon = MyCon & rst!InvoiceNumber 
     .MoveNext 
     If .EOF = True Then 
      bolF = False 
     Else 
      bolF = rst!main_id = vPK 
     End If 
    Loop 
    End With 


End Function 

注 - この変数はその値を保ち意味 - 私たちは、このように専用テーブルを一度開きます。

関連する問題