2017-07-20 12 views
0

ここまでMSSQLとAccessを使用しています。我々は、一度すべてのデータがインポートされた後、多くの更新クエリを実行する1つのアプリケーションを持っています。この特定のアプリケーションには、組み込みデータベースが必要です。 MS Accessを使用した内部ジョイントで簡単にSQLiteの更新クエリは永遠に受け取ります

私たちはSQLiteに切り替えていますが、明らかにSQLiteは非常に新しいものです。

私たちの更新クエリが正しいか、SQLiteで効率的でないようです。 彼らは永遠に(実際には決して終わらない)か働いていません。

以下の1つの例は、多対1の関係です。 "多くの"テーブルの1つのフィールドを、両方のテーブルに存在するフィールドに基づいて "One"テーブルの値に更新しようとしています。

表1(表1)
フィールド(ID) - このフィールドは、一意である
フィールド(マネージャ)

表2(多くのテーブル)
フィールド(ID) - このフィールドの値は一意ではなく、表1の(ID)フィールドの にリンクします。
フィールド(連絡先)

ここで

は、私たちのクエリです:

UPDATE [Table 2] SET [Contact] = (SELECT [Manager] FROM [Table 1] 
            WHERE [Table 2].[ID] = [Table 1].[ID]) 

我々はSQLiteのエキスパートプロフェッショナル以内にこれを試してみた、とクエリが実行を停止することはありません。更新される表2には53,391件のレコードしかありません。毎回SQLite Expertアプリケーションをシャットダウンする必要があります。それはちょうどハングアップします。

我々は次のようにトランザクション内で撮影し、当社のテストコードにこれを置く:

Using cmd as new SQLiteCommand(cnn) 
    Using transaction = cnn.BeginTransaction 
     cmd.Transaction = transaction 
     cmd.CommandText = "UPDATE [Table 2] SET [Contact] = (SELECT [Manager] FROM [Table 1] WHERE [Table 2].[ID] = [Table 1].[ID])" 
     icount = cmd.ExecuteNonQuery 
     transaction.Commit() 
    End Using 
End Using 

をこれが終了していないだけで決して。

これが働いた:より良い以上に高速なアプローチがあり

UPDATE [Table 2] SET [Contact] = (SELECT [Manager] FROM [Table 1] 
            WHERE [Table 2].[ID] = [Table 1].[ID]) 
WHERE EXISTS (Select [Manager] FROM [Table 1] 
       WHERE [Table 2].[ID] = [Table 1].[ID]) 

いないことを確認したら? WHERE EXISTSがなぜ必要なのか理解していない。

このテーブルの別のフィールドに基づいてテーブル内のフィールドを更新しようとすると、別の更新クエリの問題が発生します。再帰的な種類。

+0

これは、やや効率的ですが、フィールドはすべてのレコードに対して同じ値で更新されています:Update [Table 2] [Contact] =(SELECT [Table 1]。 ] INNER JOIN [表2] ON [表1]。[ID] = [表2]。[ID])。 – midnite11

+0

実際のテーブル定義と、持っているインデックスを表示します。 –

+0

テーブル定義では正確に何を探していますか?私はこれらのテーブルの両方が[ID]フィールドにインデックスを持っていて、それぞれが最大で4つまたは5つのフィールドを持っていることを意味します。上記のクエリは「仕事」(例:フィニッシュ)になっていますが、フィールドはすべてのレコードに対して同じ値で更新されています...ちょうど我々が最後に何かを見逃しているようです。しかし、再び我々はSQLiteを初めて使用しています。 – midnite11

答えて

-1

一般に、SQLiteはAccessよりもはるかに高速です。 DDLとデータを見ることなくどこに問題が発生しているのかを正確に知ることは不可能ですが、ID列にインデックスを作成していない可能性が最も高いのです。 Accessは、他のすべてのデータベースで、自分で明示的に定義する必要があります。

+0

両方のテーブルの両方の[ID]フィールドにインデックスがあります。 – midnite11

+1

re: "一般的にSQLiteはAccessよりもはるかに高速です" - あなたは[この回答](https://stackoverflow.com/a/35225563/2144390) –

+0

に興味があるかもしれません。しかし、私たちはMS Access DBサイズ制限に遭遇しています。したがって、選択肢はありません。私たちはMS SQLに移行したいと思っていますが、我々は組み込みデータベースの設定が必要です。 – midnite11

2

内部結合でUPDATEステートメントを使用すると、MS Accessは結合が一致した行のみを変更します。このような

相関サブクエリと平野UPDATEをやって、:

UPDATE [Table 2] SET [Contact] = (...) 

は、データベースはすべての行を変更します。 (サブクエリが行を返さない場合、SQLiteはフィールドをNULLで更新しますが、他のDBはエラーを発生させる可能性があります)。

一致する行の数がテーブルの行の数よりもはるかに小さい場合、すべての行を書き換える方がはるかに遅くなります。

UPDATE [Table 2] SET [Contact] = (...) 
WHERE EXISTS (...same subquery...) 

これは内部結合と同じ効果を持つ: それは、実際に変更されます行の数を制限することには意味になります。

+0

このフィードバックのCL - thanx。私は、私たちは何年も前から、内部SQLとMS Accessのアップデートに関連した内部結合に甘んじています。私たちはSQLiteを使い、専門家の話を聞いていただければ幸いです。 – midnite11

関連する問題