Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Bagaimana cara meningkatkan kinerja untuk INSERT massal ke tabel tertaut ODBC di Access?

Situasi ini tidak jarang terjadi ketika berhadapan dengan INSERT massal ke tabel tertaut ODBC di Access. Dalam kasus kueri Access berikut

INSERT INTO METER_DATA (MPO_REFERENCE) 
SELECT MPO_REFERENCE FROM tblTempSmartSSP

di mana [METER_DATA] adalah tabel tertaut ODBC dan [tblTempSmartSSP] adalah tabel Access lokal (asli), ODBC agak terbatas dalam seberapa pintarnya karena harus mampu mengakomodasi berbagai basis data target yang kemampuannya dapat bervariasi sangat. Sayangnya, ini sering berarti bahwa meskipun pernyataan Access SQL tunggal, apa yang sebenarnya dikirim ke database jarak jauh (tertaut) adalah INSERT (atau setara) terpisah untuk setiap baris dalam tabel lokal . Dapat dimengerti, itu bisa menjadi sangat lambat jika tabel lokal berisi banyak baris.

Opsi 1:Sisipan massal asli ke database jarak jauh

Semua database memiliki satu atau lebih mekanisme asli untuk memuat data secara massal:Microsoft SQL Server memiliki "bcp" dan BULK INSERT , dan Oracle memiliki "SQL*Loader". Mekanisme ini dioptimalkan untuk operasi massal dan biasanya akan menawarkan keuntungan kecepatan yang signifikan. Bahkan, jika data perlu diimpor ke Access dan "dipijat" sebelum ditransfer ke database jarak jauh, masih bisa lebih cepat untuk membuang data yang dimodifikasi kembali ke file teks dan kemudian mengimpornya secara massal ke database jarak jauh.

Opsi 2:Menggunakan kueri terusan di Access

Jika mekanisme impor massal bukanlah opsi yang layak, maka kemungkinan lain adalah membuat satu atau beberapa kueri terusan di Access untuk mengunggah data menggunakan pernyataan INSERT yang dapat menyisipkan lebih dari satu baris sekaligus.

Misalnya, jika database jarak jauh adalah SQL Server (2008 atau yang lebih baru) maka kita dapat menjalankan kueri Access pass-through (T-SQL) seperti ini

INSERT INTO METER_DATA (MPO_REFERENCE) VALUES (1), (2), (3)

untuk menyisipkan tiga baris dengan satu pernyataan INSERT.

Menurut jawaban untuk pertanyaan lain sebelumnya di sini sintaks yang sesuai untuk Oracle adalah

INSERT ALL
    INTO METER_DATA (MPO_REFERENCE) VALUES (1)
    INTO METER_DATA (MPO_REFERENCE) VALUES (2)
    INTO METER_DATA (MPO_REFERENCE) VALUES (3)
SELECT * FROM DUAL;

Saya menguji pendekatan ini dengan SQL Server (karena saya tidak memiliki akses ke database Oracle) menggunakan tabel [tblTempSmartSSP] asli dengan 10.000 baris. Kode ...

Sub LinkedTableTest()
    Dim cdb As DAO.Database
    Dim t0 As Single

    t0 = Timer
    Set cdb = CurrentDb
    cdb.Execute _
            "INSERT INTO METER_DATA (MPO_REFERENCE) " & _
            "SELECT MPO_REFERENCE FROM tblTempSmartSSP", _
            dbFailOnError
    Set cdb = Nothing
    Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub

... membutuhkan waktu sekitar 100 detik untuk dieksekusi di lingkungan pengujian saya.

Sebaliknya kode berikut, yang membangun INSERT multi-baris seperti yang dijelaskan di atas (menggunakan apa yang disebut Microsoft sebagai Konstruktor Nilai Tabel) ...

Sub PtqTest()
    Dim cdb As DAO.Database, rst As DAO.Recordset
    Dim t0 As Single, i As Long, valueList As String, separator As String

    t0 = Timer
    Set cdb = CurrentDb
    Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE FROM tblTempSmartSSP", dbOpenSnapshot)
    i = 0
    valueList = ""
    separator = ""
    Do Until rst.EOF
        i = i + 1
        valueList = valueList & separator & "(" & rst!MPO_REFERENCE & ")"
        If i = 1 Then
            separator = ","
        End If
        If i = 1000 Then
            SendInsert valueList
            i = 0
            valueList = ""
            separator = ""
        End If
        rst.MoveNext
    Loop
    If i > 0 Then
        SendInsert valueList
    End If
    rst.Close
    Set rst = Nothing
    Set cdb = Nothing
    Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub

Sub SendInsert(valueList As String)
    Dim cdb As DAO.Database, qdf As DAO.QueryDef

    Set cdb = CurrentDb
    Set qdf = cdb.CreateQueryDef("")
    qdf.Connect = cdb.TableDefs("METER_DATA").Connect
    qdf.ReturnsRecords = False
    qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE) VALUES " & valueList
    qdf.Execute dbFailOnError
    Set qdf = Nothing
    Set cdb = Nothing
End Sub

... membutuhkan waktu antara 1 dan 2 detik untuk menghasilkan hasil yang sama.

(Konstruktor Nilai Tabel T-SQL dibatasi untuk menyisipkan 1000 baris sekaligus, jadi kode di atas sedikit lebih rumit daripada yang seharusnya.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara membuat daftar semua tabel dalam skema di Oracle SQL?

  2. PILIH KE menggunakan Oracle

  3. Konversi Unixtime ke Datetime SQL (Oracle)

  4. Apa sebenarnya yang dilakukan tanda kutip di sekitar nama tabel?

  5. JIKA ADA kondisi tidak bekerja dengan PLSQL