• ベストアンサー

SQLの重複検索の高速化について

EXCELのデータをSQLサーバにインポートさせているのですが、 インポートの重複有無を判断するために3つのキーを 使用しています。 現状の方法としては、  Dim rsRecord As ADODB.Recordset  Set rsRecord = New ADODB.Recordset  rsRecord.Open XXXX 'レコードを開く  rsRecord.Filter = "(A='あ') And (B='い') And (C='う')" のような形でrsRecordが1以上かどうかで重複を確認しています。 (Filterのキーとなる”あ、い、う”はEXCELから取得するデータです。) 上記で重複はチェックが出来るのですが、DBの都合上、1レコード辺り 16回繰り返す必要がある為、1レコードの処理に2秒程度かかっています。 EXCELのデータ数が多いため、1回のインポート処理に30分以上掛かってしまっており、困っています。 重複チェックを高速にする良い方法はないでしょうか。 データベース初心者のため、色々方法を探した結果、上のような 処理以外見当たらず困っています。よろしくお願いします。

  • Boo2
  • お礼率25% (6/24)

質問者が選んだベストアンサー

  • ベストアンサー
noname#140971
noname#140971
回答No.1

IF Nnot DBLookup(列名,テーブル名, 条件, False) Then   インポート手続き End If 次のDBLookup関数は、pubCNNSTRINGをSQL Sereverのそれにすれば動作します。 フィルターをかけるよりは速いとは思います。 ただ、接続と切断を繰り返すのが難点。 ただ、AccessのDLookup関数とくらべたら150倍速で動作するのは間違いありません。 ですから<1レコードの処理に2秒>という遅さではないのは確実だと思います。 Public Const pubCNNSTRING="XXXXXXXXXX" Public Function DBLookup(ByVal strField As String, _              ByVal strTable As String, _              Optional ByVal strWhere As String = "", _              Optional ByVal ReturnValue = Null) As Variant On Error GoTo Err_DBLookup    Dim DataValue    Dim strQuerySQL As String    Dim rst     As ADODB.Recordset    Set rst = New ADODB.Recordset    strQuerySQL = "SELECT " & strField & " FROM " & strTable    If Len(strWhere) > 0 Then      strQuerySQL = strQuerySQL & " WHERE " & strWhere    End If    With rst      .Open strQuerySQL, _         pubCNNSTRING, _         adOpenStatic, _         adLockReadOnly      If Not .BOF Then        .MoveFirst        DataValue = .Fields(0)      End If    End With Exit_DBLookup: On Error Resume Next    rst.Close    Set rst = Nothing    DBLookup = IIf(Len(DataValue & "") = 0, ReturnValue, DataValue)    Exit Function Err_DBLookup:    MsgBox "SELECT 文の実行時にエラーが発生しました。(DBLookup)" & Chr$(13) & Chr$(13) & _       "・Err.Description=" & Err.Description & Chr$(13) & _       "・SQL Text=" & strQuerySQL, _       vbExclamation, " 関数エラーメッセージ"    Resume Exit_DBLookup End Function ※SQL文を直接渡せば、もうチビットは高速化します。 ※DBCount()を使う手もありますが、どっちが速いか不明。 ※「一時的にWHERE節に関連する列にインデックス」は試す価値がとも。 http://www.accessclub.jp/ado/18.html SEEKメソッドはDAOでしか使ったことがありません。 しかし、DBLookup()のSEEK版なら、もっと速いかもです。

Boo2
質問者

お礼

追伸ですいません。 色々試した結果、出来ました。 1レコードで1秒未満で実行できました。 ありがとうございます!!

Boo2
質問者

補足

早々なご回答ありがとうございました。 説明が不足していたのですが、インポートするEXCELの1列の情報の中で、16個のDBのレコードが出来る為、DBLookUpでそういった処理は出来ますでしょうか。 イメージとしてはこんな感じの事をしています。 [EXCEL] Index,Title,Ver1,Ver2,…,Ver16 [DB] Index,Title,Ver DBのVerが、Excelの一列にあるVer1~16のデータが別レコードとして、存在しており、この3つでEXCELデータがDB内に存在するのかを確認しています。 この場合DBLookUpへの入力は、WHERE句に、Index,Title,Verの比較条件をいれ、Verの条件を1~16で指定することになるのでしょうか。 DB初心者で申し訳ありませんが、よろしくお願いします。

その他の回答 (1)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

件数次第ですが、1000~2000件までならば、Excelのデータを読み込んで、 "SELECT tmp.* FROM   (SELECT '値' A,'値' B, '値' C UNION ALL SELECT '値','値', '値' UNION ALL ...) tmp INNER JOIN (SQL Serverのテーブル) t ON t.A=tmp.A AND t.B=tmp.B AND t.C=tmp.C" という文字列を組み上げて実行するという手もあります。 これだと1クエリで全件チェックされ、返って来たものが重複しています。 (長い文字列なので、Mid$などを使って組み上げます) 組み上げた中のtmpに当たる部分は、頭に"INSERT INTO (SQL Serverのテーブル)" と付ければ、INSERTも1クエリでできます。 数千件以上あるなら、一旦ExcelのデータをSQL Server側のワークテーブルに入れた方がいいと思います。 入れてしまえば、重複チェック/チェック後のINSERTは1クエリでできます。

Boo2
質問者

お礼

回答ありがとうございます。 ただ、SQLに関して、知識が浅いため、一つ一つのキーワードは わかっても今ひとつ理解できず、回答を活かせませんでした。。。 もう少し、SQLを勉強します。

関連するQ&A

  • 重複データを除いてインポート

    ACCESS2000を使用しています。 FDのデータをテーブルにインポートしたいのですが、重複しているデータはインポートしたくありません。 キーとなるものは、「個人コード」と「入力日」です。 同じ個人コードでも入力日が違えば別データとしてインポートしたいと思います。 アドバイスの程よろしくお願いします。 ※VBAを使って処理をするつもりです。 複数回の手順で行う方法でもよいので、良い方法があれば教えて下さい。

  • sqlで重複チェック

    よろしくお願いします。 会員サイトのマイページにて住所などの情報を更新するページを作成しておりますが、つまづいております。 情報の更新は住所や電話番号なのですが、住所のみを更新する際、電話番号の重複チェックで、 重複チェック用にデータをSELECTした時、自分自身のレコードが含まれているため、自分自身のレコードで重複となってしまい、先に進めません。 WHERE句をうまく利用すればできると思うのですが思いつきません。。。 どのようにSQLを書けばいいのかご伝授ください。

    • ベストアンサー
    • MySQL
  • EXCELで重複行のデータを削除したいと思っています。

    EXCELで重複行のデータを削除したいと思っています。 フィルタの重複するレコードは無視するにチェックをいれる方法は知っているのですが、 この方法だと新しく出来たデータ列が数式ではなく数式の計算結果でデータ列が出来てしまいます。 どうしたら数式のままで重複データを削除出来るのでしょうか?

  • CSVファイルの重複チェック

    あるデータがあり、そのデータが毎日増えていくと仮定します。 (もともと元データが100件あって、毎日10件づつ増えていくようなイメージ) 毎日10件づつ増えていくデータの中で、もともとあった100件と 重複しているものがあるかどうかのチェックを効率的に行いたいと考えています。 イメージとしては元データはaccessかエクセル上に存在していて、 毎日増えていくデータをCSVインポートか何かで取り込んで、 マクロか何かでチェックをかけると、 重複しているかどうかのチェックをかけてくれるような仕組みが無いか探しています。 (重複していないものの一覧をエクスポート および 重複していないものを元データに追加してくれる とかいう処理があるとよりありがたいです) 手動でやると大変なので、そういったことが出来るツールなど フリーソフトでご存知の方、もしくはエクセルマクロで簡単に出来るよ といったアドバイスいただけると大変助かります。 WEBシステムでももちろん結構です。 質問の中で不明確な点がありましたら追加で補足しますのでご指摘ください。

  • ACCESS インポート時の重複チェック

    ACCESS2000を使用しています。 FDのデータをテーブルにインポートする処理があるのですが、データが重複しているかどうかのチェックはどうすれば出来るのでしょうか。 ご存知の方がいれば教えてください。 よろしくお願いします。 ※重複をチェックする項目は「個人コード」です。

  • phpで重複チェック

    phpの重複チェック phpで配列の重複データをチェックして、重複しているデータを表示しようとしています。 foreach ($arry as $key => $value) { $err_count = 0; foreach ($arry as $key => $value2) { if ($value == $value2) { $err_count++; if ($err_count >= 2) { echo "重複".$value2; } } } } としているのですが、 同じモノが2回表示されて困っています。 重複しているデータは一回だけ表示したいのですが、 なにか方法ないでしょうか?

    • ベストアンサー
    • PHP
  • 重複レコードを高速で取得するSQL

    Access(mdb)から約2万件レコードのあるテーブルがあるとします。 列数は20ほど。 その中から、3つの列において重複しているレコードを取得したいのですが、 高速に取得する方法はありますでしょうか? (VB.NETで、重複レコードをユーザーに示す処理を作成したいのです) 以下のSQLを試したところ、1分以上時間がかかってしまいました。 ----------------------------- SELECT * FROM テーブルA table1 WHERE EXISTS ( SELECT * FROM テーブルA table2 WHERE table1.列A = table2.列A   table1.列B = table2.列B   table1.列C = table2.列C GROUP BY table2.列A HAVING COUNT(table2.列A) > 1 ) ----------------------------- アドバイスをお願いします。

  • フィルタオプションの重複削除

    エクセル2003を使っています。 フィルタオプションを使って「重複するレコードは無視する」にチェックを入れ、重複を非表示にしたいのですが、最初の重複するデータが残り、次に重複するデータは非表示されます。 例えば、1行目にあいうえお 2行目にかきくけこ 3行目にさしすせそ 4行目にあいうえお 5行目にかきくけこ があるとします。 フィルタオプションを使って「重複するレコードは無視する」にチェックを入れると、 1行目にあいうえお 2行目にかきくけこ 3行目にさしすせそ 4行目にあいうえお となり、重複している、かきくけこは非表示になっているのですが、同じく重複しているあいうえおは表示されたままです。 これはなぜでしょうか? よろしくお願い致します。

  • FILEMAKER6の重複するレコードの検索について。

    現在数万件のレコードを扱っていますが、自己連結リレーションを使用して計算フィールドで重複するレコードを割り出し、そのフィールドで検索をかけると索引設定ができないため検索に時間がかかってしまいます。 これ以外の方法で処理に時間をかけずに重複するレコードを特定する方法があれば是非教えてください。よろしくお願いします。

  • キーが重複したレコードを無視してリストアする方法は?

    キーが重複したレコードがバックアップファイル内にあっても、それを無視して重複していないレコードだけをリストアする方法は無いでしょうか? 現在、osqlコマンドを用いてテーブルの既存データに追加する形でリストアするプログラムを作っているのですが、重複したレコードがあると処理が中断してしまうため、残った重複のないレコードを追加できずに困っています。 サーバはSQL Server 2000 使用言語はVB.NET になります。 ご教授宜しくお願い致します。