PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tại sao thậm chí sử dụng * DB.exec () hoặc các câu lệnh chuẩn bị sẵn trong Golang?

"Tại sao thậm chí sử dụng db.Exec ()":

Đúng là bạn có thể sử dụng db.Execdb.Query có thể hoán đổi cho nhau để thực hiện các câu lệnh sql giống nhau, tuy nhiên hai phương thức trả về các kiểu kết quả khác nhau. Nếu được trình điều khiển triển khai, kết quả trả về từ db.Exec có thể cho bạn biết có bao nhiêu hàng bị ảnh hưởng bởi truy vấn, trong khi db.Query sẽ trả về đối tượng hàng thay thế.

Ví dụ:giả sử bạn muốn thực thi DELETE và bạn muốn biết có bao nhiêu hàng đã bị xóa bởi nó. Bạn có thể làm điều đó theo cách thích hợp:

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)

hoặc cách chi tiết hơn và khách quan hơn, tốn kém hơn:

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)

Có một cách thứ 3 bạn có thể làm điều này với sự kết hợp của các CTE postgres, SELECT COUNT , db.QueryRowrow.Scan nhưng tôi không nghĩ rằng một ví dụ là cần thiết để cho thấy cách tiếp cận sẽ không hợp lý như thế nào khi so sánh với db.Exec .

Một lý do khác để sử dụng db.Exec over db.Query là khi bạn không quan tâm đến kết quả trả về, khi tất cả những gì bạn cần là thực hiện truy vấn và kiểm tra xem có lỗi hay không. Trong trường hợp như vậy, bạn có thể làm điều này:

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

Mặt khác, bạn không thể (có thể nhưng không nên) làm điều này:

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

Làm điều này, sau một thời gian ngắn, chương trình của bạn sẽ phát ra lỗi với lỗi tương tự như too many connections open . Điều này là do bạn đang loại bỏ db.Rows được trả về giá trị mà không cần thực hiện Close bắt buộc trước gọi nó, và do đó bạn kết thúc với số lượng kết nối mở tăng lên và cuối cùng đạt đến giới hạn của máy chủ.

"hoặc câu lệnh chuẩn bị sẵn trong Golang?":

Tôi không nghĩ rằng cuốn sách bạn đã trích dẫn là chính xác. Ít nhất đối với tôi, nó giống như có hay không một db.Query lệnh gọi tạo ra một câu lệnh chuẩn bị mới mọi lúc phụ thuộc vào trình điều khiển bạn đang sử dụng.

Ví dụ xem hai phần này của queryDC (một phương thức chưa được báo cáo được gọi bởi db.Query ):không có tuyên bố chuẩn bị và với tuyên bố đã chuẩn bị.

Bất kể cuốn sách có đúng hay không là db.Stmt được tạo bởi db.Query sẽ là, trừ khi có một số bộ nhớ đệm nội bộ đang diễn ra, bị loại bỏ sau khi bạn đóng Rows được trả về vật. Nếu thay vào đó, bạn hãy gọi thủ công db.Prepare và sau đó lưu vào bộ nhớ cache và sử dụng lại db.Stmt đã trả về bạn có thể cải thiện hiệu suất của các truy vấn cần được thực thi thường xuyên.

Để hiểu cách sử dụng một tuyên bố đã chuẩn bị để tối ưu hóa hiệu suất, bạn có thể xem tài liệu chính thức: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. Các truy vấn PostgreSQL Yêu thích của tôi và Tại sao Chúng lại Quan trọng

  2. Cách kiểm tra xem một bảng có tồn tại trong một lược đồ nhất định hay không

  3. Tổng quan về các cột được tạo cho PostgreSQL

  4. Cần tìm gì nếu Bản sao PostgreSQL của bạn đang bị trễ

  5. Tránh bế tắc PostgreSQL khi thực hiện cập nhật hàng loạt và thao tác xóa