#52 | クエリパフォーマンスの定石を試す(6) | ||||||||||||||||
クエリ(SQL文)のパフォーマンスを上げるための”定石”のひとつとして、『テーブル名には別名を使う』というものがあります。 通常、SELECT文のあとに列挙するフィールド名は、「フィールド1, フィールド2, フィールド3,・・・・」というように単にフィールド名をカンマで並べるだけです。 一方、複数のテーブルなどを結合しているクエリや、あるいは単一テーブルでもAccessのクエリのデザインビューで自動生成されるSQL文の場合には、「テーブル名1.フィールド1, テーブル名1.フィールド2,・・・・」というように、フィールド名の前にそのテーブル名が明示的されます。 このとき、テーブル名として、データベース内にあるテーブル名を直接指定するよりも、テーブル名を別名で定義し、その別名を使って「別名.フィールド1, 別名.フィールド2,・・・・」というようにした方がパフォーマンスがよいというのが定石の考え方です。 その理由としては、実行時のパフォーマンスではなく、SQL文の解釈に伴う処理が軽くなるというものです。よほど複雑なクエリ、あるいはSQL文の解釈を連発的に必要とするような処理でもない限り、その”解釈に要する時間”というのが大きな影響を及ぼすということはなさそうに思えるのですが、今回は一応その点について実際にテストプログラムを走らせて確認してみることにします。 なお、テーブルの別名の定義は「FROM tbl受注明細 tbl」のように、「FROM テーブル名 別名」という書き方になります。 今回のテスト用のコードは次のようなものです。 2つのパターンを試していますが、違いは前述の通り、フィールド名の前にテーブルそのものの名前を直接指定するか、別名を指定するかだけの違いです。 レコードセットを開いて全レコードをトレースするとういうコードですが、レコードの操作は今回の場合はあまり関係なく、SQL文を組み立てたあと、そのSQL文を元にレコードセットを開く部分だけの処理時間の差が出てくると想像されます。 Sub QueryPerformance_6() Dim dbs As Database Dim rst As Recordset Dim strSQL As String Dim iintLoop As Integer ts_Watch "処理開始", True Set dbs = CurrentDb 'テーブル名をそのまま指定 For iintLoop = 1 To 20 strSQL = "SELECT tbl受注明細.受注コード, tbl受注明細.商品コード, tbl受注明細.数量 " & _ "FROM tbl受注明細 " & _ "WHERE 数量 > 900" Set rst = dbs.OpenRecordset(strSQL) With rst Do Until .EOF .MoveNext Loop .Close End With ts_Watch "テーブル名をそのまま指定" Next iintLoop 'テーブル名を別名指定 For iintLoop = 1 To 20 strSQL = "SELECT tbl.受注コード, tbl.商品コード, tbl.数量 " & _ "FROM tbl受注明細 tbl " & _ "WHERE 数量 > 900" Set rst = dbs.OpenRecordset(strSQL) With rst Do Until .EOF .MoveNext Loop .Close End With ts_Watch "テーブル名を別名指定" Next iintLoop End Sub その結果は次のようになりました(単位は秒)。
ご覧のように、ほぼ完全に”違いはない!”という結果になっています。 やはり想像通り、”SQL文の解釈”に要する時間は全体としては微々たるものだからでしょう。今回のプログラムでは、20回のループを回すだけなので、たった20回のSQL文の解釈など比較するにも値しない少しの時間で実行されてしまうということではないでしょうか?。 しかも、今回は非常にシンプルなSQLです。もしももっと長いSQL文、もっと複雑なSQL文、さらにそれらが一度に何百何千と連続して発行されるような処理がもしあるとすれば、そのようなときにはちょっと試してみる価値 は残されているかもしれません。 |
|||||||||||||||||
|
Copyright © T'sWare All rights reserved |