2013-07-25 18 views
7

Hãy để tôi giải thích bằng ví dụ. Hãy xem xét bảng sau:Cách nhanh nhất để xóa tất cả khách hàng khỏi SQL Server dựa trên khách hàng đó không đáp ứng một tiêu chí duy nhất là

Customer Id | Food 
------------+--------- 
1   | Pizza  
1   | Burger 
1   | Hot Dog 
2   | Milkshake  
2   | Burger 
3   | Pizza 

Tôi muốn xóa tất cả các hồ sơ cho khách hàng có KHÔNG BAO GIỜ ra lệnh Pizza. Vì vậy, tôi chỉ nên để này (khách hàng # 2 bị xóa):

Customer Id | Food 
------------+--------- 
1   | Pizza  
1   | Burger 
1   | Hot Dog 
3   | Pizza 

Tôi biết tôi có thể làm một NOT IN nhưng hiệu suất là khủng khiếp.

Cách hiệu quả nhất để viết truy vấn này để đạt được điều này so với 100.000 bản ghi trong SQL Server là gì?

+0

Sẽ hữu ích nếu bạn đưa ra truy vấn bạn đã thử. Bạn đã thử ['NOT EXISTS'] (http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/) chưa? – Appulus

+1

NẾU phiên bản NOT EXISTS vẫn chưa đủ nhanh cho bạn, hãy thử sử dụng 'DELETE TOP (x) FROM FROM WHERE NOT EXISTS ....' trong đó x là kích thước lô. Nói 10.000. Điều này sẽ cho phép bạn chia nhỏ việc xóa thành các lô và giảm kích thước giao dịch. –

Trả lời

9

Một đơn giản NOT EXISTS nên efficient với chỉ số thích hợp.

DELETE c1 FROM Customers c1 
WHERE NOT EXISTS 
(
    SELECT 1 FROM Customers c2 
    WHERE c1.[Customer Id] = c2.[Customer Id] 
    AND c2.[Food] = 'Pizza' 
); 

Demo

Tạo một chỉ mục trên [Customer Id] và một chỉ số không clustered trên Food.

+2

Cảm ơn Tim. Liên kết tới http://www.sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join rất hữu ích. –

4

thế nào về NOT EXISTS

DELETE a 
FROM table1 a 
WHERE NOT EXISTS 
     (
      SELECT 1 
      FROM table1 b 
      WHERE a.customerID = b.customerID AND 
        b.Food = 'Pizza' 
     ) 
0

thử

delete t from t 
left join (select distinct [Customer Id] from t where Food='Pizza') t2 
on t.[Customer Id]=t2.[Customer Id] 
where t2.[Customer Id] is null 

SQLFiddle demo

+2

[Mẫu 'LEFT OUTER JOIN' này luôn hoạt động kém nhất trong số các tùy chọn khác nhau] (http://www.sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join). –

0
  • Nếu kích thước bảng là rất lớn, hãy thử xóa theo lô. hoặc
  • Di chuyển các bản ghi không cần xóa trong bảng tạm thời.Tắt bớt bảng chính và sau đó di chuyển phần còn lại của bản ghi từ bảng tạm thời sang bảng chính.