2010-10-26 25 views
8

Trước hết, hãy để tôi chỉ nói rằng tôi đang sử dụng khung công tác PHP Yii, vì vậy tôi muốn ở lại trong bộ xác định câu lệnh SQL nếu có thể. Tôi biết tôi có lẽ có thể tạo ra một câu lệnh SQL dài rất lớn có thể làm mọi thứ, nhưng tôi không muốn đến đó.Trong MySQL, có nhanh hơn để xóa và sau đó chèn hoặc là nó nhanh hơn để cập nhật các hàng hiện có?

OK, hãy tưởng tượng tôi có bảng Người dùng và bảng FavColors. Sau đó, tôi có một hình thức mà người dùng có thể chọn tùy chọn màu sắc của họ bằng cách chọn một hoặc nhiều hộp kiểm từ một danh sách lớn các màu sắc có thể.

Các kết quả này được lưu trữ dưới dạng nhiều hàng trong bảng FavColors như thế này (id, user_id, color_id).

Bây giờ hãy tưởng tượng người dùng đi vào và thay đổi tùy chọn màu sắc của họ. Trong trường hợp này, cách hiệu quả nhất để có được các sở thích màu mới vào cơ sở dữ liệu là gì?

Lựa chọn 1:

  • Thực hiện hàng loạt xóa tất cả các hàng nơi user_id phù hợp
  • Sau đó làm một chèn khối lượng của tất cả các hàng mới

Phương án 2:

  • Đi qua từng c hàng hiện tại để xem những gì đã thay đổi và cập nhật cho phù hợp
  • Nếu cần thêm nhiều hàng, hãy thực hiện điều đó.
  • Nếu các hàng cần xóa, hãy thực hiện điều đó.

Tôi thích tùy chọn vì nó chỉ yêu cầu hai câu lệnh, nhưng điều gì đó chỉ cảm thấy sai khi xóa một hàng để có khả năng đặt lại gần như cùng một dữ liệu chính xác. giá trị cao hơn nhanh hơn, và tôi không biết liệu có nên tránh điều đó bất cứ khi nào có thể.

Tùy chọn 2 sẽ yêu cầu nhiều công việc lập trình hơn, nhưng sẽ ngăn các tình huống mà tôi xóa một hàng chỉ để tạo lại. Tuy nhiên, việc thêm nhiều tải trong PHP có thể không đáng để giảm tải cho MySQL.

Mọi suy nghĩ? Tất cả các bạn sẽ làm gì?

Trả lời

9

UPDATE nhanh hơn rất nhiều. Khi bạn UPDATE, các bản ghi bảng chỉ được ghi lại bằng dữ liệu mới. Và tất cả điều này phải được thực hiện lại trên INSERT.

Khi bạn DELETE, chỉ mục sẽ được cập nhật (hãy nhớ, bạn xóa toàn bộ hàng, không chỉ các cột bạn cần sửa đổi) và khối dữ liệu có thể được di chuyển (nếu bạn đạt giới hạn PCTFREE). Ngoài ra, việc xóa và thêm các thay đổi mới sẽ ghi lại các ID trên auto_increment, vì vậy nếu các bản ghi đó có các mối quan hệ bị hỏng hoặc cũng sẽ cần các bản cập nhật. Tôi sẽ đi cho UPDATE.

Đó là lý do bạn nên thích INSERT ... ON DUPLICATE KEY UPDATE thay vì REPLACE.

Một cựu là một hoạt động UPDATE trong trường hợp có vi phạm quan trọng, trong khi một thứ hai là DELETE/INSERT

UPDATE: Dưới đây là một ví dụ INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;

Để biết thêm thông tin chi tiết đọc cập nhật documentation

+1

Nếu cập nhật trường được lập chỉ mục, chỉ mục được cập nhật quá –

+0

@OMG vâng! Quên đề cập đến điều đó. Tốt mà bạn đã làm ... –

+0

Cảm ơn, điều đó có ý nghĩa. Thật không may, khi bạn đang sử dụng một khung công tác dựa trên ActiveRecord, việc tạo một câu lệnh SQL tùy chỉnh không phải lúc nào cũng dễ dàng và bao gồm "CHERTN ... ON UPDATE DUPLICATE KEY UPDATE". Nếu tôi làm điều đó, tôi sẽ phải tạo một truy vấn theo cách thủ công và truy vấn đó nhiều khả năng sẽ không dịch nếu tôi cần chuyển đổi DBMS trong tương lai. –

1

Philip, Bạn đã thử làm những câu đã chuẩn bị chưa? Với các câu lệnh chuẩn bị, bạn có thể thực hiện một truy vấn với các tham số khác nhau và gọi nó nhiều lần. Vào cuối vòng lặp của bạn, bạn có thể thực hiện tất cả chúng với lượng thời gian chờ mạng tối thiểu. Tôi đã sử dụng các câu lệnh chuẩn bị với php và nó hoạt động rất tốt. Ít khó hiểu hơn so với các câu lệnh được chuẩn bị java.

Các vấn đề liên quan