PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Mengapa bahkan menggunakan *DB.exec() atau pernyataan yang disiapkan di Golang?

"Mengapa bahkan menggunakan db.Exec()":

Memang benar bahwa Anda dapat menggunakan db.Exec dan db.Query secara bergantian untuk mengeksekusi pernyataan sql yang sama namun kedua metode mengembalikan jenis hasil yang berbeda. Jika diimplementasikan oleh driver, hasilnya dikembalikan dari db.Exec dapat memberi tahu Anda berapa banyak baris yang terpengaruh oleh kueri, sementara db.Query akan mengembalikan objek baris sebagai gantinya.

Misalnya katakanlah Anda ingin menjalankan DELETE pernyataan dan Anda ingin tahu berapa banyak baris yang dihapus olehnya. Anda dapat melakukannya dengan cara yang benar:

res, err := db.Exec(`DELETE FROM my_table WHERE expires_at = $1`, time.Now())
if err != nil {
    panic(err)
}

numDeleted, err := res.RowsAffected()
if err != nil {
    panic(err)
}
print(numDeleted)

atau cara yang lebih bertele-tele dan secara objektif lebih mahal:

rows, err := db.Query(`DELETE FROM my_table WHERE expires_at = $1 RETURNING *`, time.Now())
if err != nil {
    panic(err)
}
defer rows.Close()

var numDelete int
for rows.Next() {
    numDeleted += 1
}
if err := rows.Err(); err != nil {
    panic(err)
}
print(numDeleted)

Ada cara ketiga Anda dapat melakukan ini dengan kombinasi CTE postgres, SELECT COUNT , db.QueryRow dan row.Scan tapi saya rasa contoh tidak diperlukan untuk menunjukkan betapa tidak masuk akalnya suatu pendekatan jika dibandingkan dengan db.Exec .

Alasan lain untuk menggunakan db.Exec melalui db.Query adalah ketika Anda tidak peduli dengan hasil yang dikembalikan, ketika yang Anda butuhkan hanyalah menjalankan kueri dan memeriksa apakah ada kesalahan atau tidak. Dalam kasus seperti ini, Anda dapat melakukan ini:

if _, err := db.Exec(`<my_sql_query>`); err != nil {
    panic(err)
}

Di sisi lain, Anda tidak bisa (Anda bisa tetapi tidak boleh) melakukan ini:

if _, err := db.Query(`<my_sql_query>`); err != nil {
    panic(err)
}

Melakukan ini, setelah beberapa saat, program Anda akan panik dengan kesalahan yang mengatakan sesuatu yang mirip dengan too many connections open . Ini karena Anda membuang db.Rows . yang dikembalikan nilai tanpa terlebih dahulu membuat wajib Close panggil saja, dan Anda akan berakhir dengan jumlah koneksi terbuka yang meningkat dan akhirnya mencapai batas server.

"atau menyiapkan pernyataan dalam bahasa Golang?":

Saya rasa buku yang Anda kutip itu tidak benar. Setidaknya bagi saya itu terlihat seperti apakah db.Query . atau tidak panggilan membuat pernyataan baru yang disiapkan setiap kali tergantung pada driver yang Anda gunakan.

Lihat misalnya dua bagian queryDC ini (metode yang tidak diekspor disebut oleh db.Query ):tanpa pernyataan siap dan dengan pernyataan siap.

Terlepas dari apakah buku itu benar atau tidak sebuah db.Stmt dibuat oleh db.Query akan, kecuali ada beberapa caching internal yang terjadi, dibuang setelah Anda menutup Rows yang dikembalikan obyek. Jika Anda secara manual memanggil db.Prepare lalu tembolok dan gunakan kembali db.Stmt yang dikembalikan Anda berpotensi dapat meningkatkan kinerja kueri yang perlu sering dijalankan.

Untuk memahami bagaimana pernyataan yang disiapkan dapat digunakan untuk mengoptimalkan kinerja, Anda dapat melihat dokumentasi resmi:https://www.postgresql.org/docs/current/static/sql-prepare.html




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Temukan perbedaan antara stempel waktu dalam hitungan detik di PostgreSQL

  2. Mengapa pg_restore berhasil kembali tetapi tidak benar-benar memulihkan database saya?

  3. Apa yang Harus Diperhatikan jika Replikasi PostgreSQL Anda Lagging

  4. Bagaimana cara menulis DataFrame ke tabel postgres?

  5. Wadah Docker untuk Postgres 9.1 tidak mengekspos port 5432 ke host