hatena
hatena
2021/06/22 (火) 13:45:49
mayuさん、ベンチマーク実験ありがとうございました。非常に示唆に富む興味深い実験ですね。
あと、PC性能すごいですね。当方の環境でテストしたら数倍時間かかりました(;^_^A
100万件のデータとなると連番を入力しておいても結構時間がかかるようです。
そこでテーブルに連番を入力するのではなく StartTime フィールドを追加して、"END"レコードの方に対応する"START"の時刻を格納するという方法にしてみました。
表1に日付/時刻型のフィールドを追加して、名前を StartTime とします
下記のVBAを実行します。
Public Sub SetStarTime()
Const strSQL = _
"SELECT * FROM 表1 ORDER BY EVENT, E_Time, E_Cond DESC;"
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
Do Until rs.EOF
Dim stime As Date
If rs!E_Cond = "START" Then
stime = rs!E_Time
Else
rs.Edit
rs!StartTime = stime
rs.Update
End If
rs.MoveNext
Loop
rs.Close
MsgBox "StarTime入力完了"
End Sub
クエリは下記のようにシンプルになります。
SELECT
EVENT,
StartTime,
E_Time,
DateDiff('s', StartTime, E_Time) AS DURATION
FROM
表1
WHERE
E_Cond = "END";
E_Condにインデックスを貼っておいたらほぼ一瞬で表示されました。
通報 ...
発想の柔軟さ、パフォーマンスへの配慮、さすがhatenaさんです。
標準SQLのウィンドウ関数 LAG が利用可能な SQLServer だと
以下のSQLで hatenaさんと同等のロジックになりそうですね。
些細なことですけどENDをチェックする形にするとENDがあればSTARTがあることが保証される(はず)なのでIf判定がおよそ半分減らせますね(処理時間の差がわからない程度の差ですが)
VBAで連番振ってSQLって方式はどうせVBA使うならこれやればいいじゃないなのでACCESS上の話である以上ナンセンスなんですよね
実は対抗としては>> 14でりんごさんが試されている通り元のテーブルに手を入れてあげればn²オーダーに見えるクエリでも爆速で動くという手法だと思います。主キーインデックスのないテーブルに主キーインデックスを設定してスカラサブクエリで表示するという手法でもVBAだけと遜色ない速度がでます
結局のところテーブル設計をしっかりやりましょうという話です
改めて考えてみたんですがSTARTの判定はよくないですね
ENDのレコードの存在が保証されない場合データが漏れます
ENDのレコードの存在が保証されているなら奇数偶数でSTART/ENDがきれいに出現するのでIF判定が必要ないです