- 締切済み
Access結合後の短いテキスト型のインデックス
Accessの検索にて、テーブルA LEFT JOIN テーブルB で外部結合し、 WHERE句でテーブルBの短いテキスト型を抽出条件にすると、検索が遅くなります。 【テーブル定義】 テーブルA( ・年月日(日付/時刻、重複ありインデックス) ・コード(短テキスト、重複ありインデックス) ・属性あ(短テキスト、重複ありインデックス) ・属性い(短テキスト、重複ありインデックス) ) テーブルB( ・コード(短テキスト、主KEY) ・属性う(短テキスト、重複ありインデックス) ・属性え(数値、重複ありインデックス) ) 【件数】 テーブルA:15万件 テーブルB:500件 =====SQLここから===== SELECT * FROM テーブルA LEFT JOIN テーブルB ON テーブルA.コード = テーブルB.コード WHERE 属性あ IS NULL AND 属性い = 'あああ' AND 属性う = 'アアア' AND 属性え = 1 GROUP BY 年月日、 属性う =====SQLここまで===== この検索SQLは遅い(1分30秒くらい)のですが 『AND 属性う = 'アアア'』を削除すると 10秒くらいに速くなります。 ”属性う” のインデックスが効いてないように見えるのですが どのようにチューニングしたら速くなるでしょうか? エクセルからLAN越しにDAO接続してSQL実行してます。 AccessはOffice365(バージョン1902)です。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- chayamati
- ベストアンサー率41% (260/624)
その後如何ですか あなたのSQL文がこちらでは実行不可です ------------------------------------------------- SELECT * FROM テーブルA LEFT JOIN テーブルB ON テーブルA.コード = テーブルB.コード WHERE 属性あ IS NULL AND 属性い = 'あああ'AND 属性う 'アアア'AND 属性え = 1 GROUP BY 年月日,属性う --------------------------------------------------------------------------- 1.自分は'あああ' 'アアア'等文字定数を命令文に使うことは極力避けています フォーム上にテキストボック、コンボボックスを配置してエンドユーザーに委ねています 参照用のテーブルをコンボボックスに配置してミス入力の回避と処理効率の向上 2.GROUP BYはSUM()とセットではないですか > FROM テーブルA LEFT JOIN テーブルB ON 3.関連付けは参照整合性のリレーションのみにしています Accessだけのときは問題ないのですが、外部よりインポートで不都合な情報があります この時点でインポートした情報から不足したレコードを追加します >この検索SQLは遅い(1分30秒くらい)のですが 4. 条件付きクエリ瞬時に開きます 5.テーブルA 15万レコード テーブルB 500レコード に S_属性あ、S_属性い、S_属性う、S_属性えの4つテーブルを追加して作成しました 重複なしのフィールドは後のレコードは、はじき返されます 添付のように15万レコードのテーブルAよりテーブルBへのインポートは10秒 背景が色付のラベルボックッスはクリックで実行します ----------------------------------------------------------------------------- Option Compare Database Option Explicit Private Sub クエリ起動_Click() 開始時刻 = Now() Do C md .Open Query "クエリ1" クエリ時間 = Now() - 開始時刻 End Sub Private Sub テーブルの正規化_Click() Do C md .Set Warnings False 開始時刻 = Now() Do C md .Run SQL ("INSERT into テーブルB(コード) select コード from テーブルA; ") 所要時間 = Now() - 開始時刻 開始時刻 = Now() Do C md .Run SQL ("delete from s_属性あ ;") Do C md .Run SQL ("insert into S_属性あ(属性あ) select 属性あ from テーブルA ;") あ時間 = Now() - 開始時刻 開始時刻 = Now() Do C md .Run SQL ("delete From s_属性い ;") Do C md .Run SQL ("INSERT into S_属性い(属性い) select 属性い from テーブルA; ") い時間 = Now() - 開始時刻 開始時刻 = Now() Do C md .Run SQL ("delete From s_属性う ;") Do C md .Run SQL ("INSERT into S_属性う(属性う) select 属性う from テーブルB; ") う時間 = Now() - 開始時刻 開始時刻 = Now() Do C md .Run SQL ("delete From s_属性え ;") Do C md .Run SQL ("INSERT into S_属性え(属性え) select 属性え from テーブルB; ") え時間 = Now() - 開始時刻 Do C md .Set Warnings True End Sub ----------------------------------------------------------------------------- 文中以下語句は回答として記述出来ませんので間に空白を入れました 空白を除去して下さい D o C m d. O p e n Query "クエリ1" D o C m d .S et Warnings False Do Cm d . Run SQL D o C m d . R u n SQL Do Cm d . S et Warnings True
- chayamati
- ベストアンサー率41% (260/624)
こんばんは 確証はありませんが 1.グループ化の対象フィールドには演算式(カウントor SUM 等)が必要では また ワイルドカード「*」は使えないのではないですか また 処理結果になにがしかのリストが得られますか 2.テーブルBに無いコードの処理に時間をとっているのでは 試しに ------------------------------------------------------------------------------ SELECT * from テーブルA RIGHT JOIN ON テーブルA.コード = テーブルB.コード WHERE 属性あ IS ,NULL AND 属性い='あああ' AND 属性う = 'アアア'AND 属性え = 1 GROUP BY 年月日,属性う ------------------------------------------------------------------------------ とすると処理時間に変化はありませんか
お礼
回答ありがとうございます。 今手元に検証環境がないため月曜以降に試します。