2015-09-28 17 views
7

Tôi có cơ sở dữ liệu Azure Sql có kích thước khoảng 9 GB. Nó phục vụ một ứng dụng web xử lý khoảng 135K yêu cầu mỗi giờ. Hầu hết các dữ liệu là tạm thời, nó sống trong cơ sở dữ liệu từ một vài phút đến năm ngày và bị xóa. Khoảng 10 GB di chuyển qua cơ sở dữ liệu mỗi ngày.Tại sao cơ sở dữ liệu SQL Azure của tôi xóa hiệu suất truy vấn quá chậm?

Tôi đã cố chạy truy vấn xóa trên bảng để xóa khoảng 250.000 bản ghi trong tổng số 350.000 bản ghi. Khoảng 10 phần trăm của các bản ghi có một hoặc hai giá trị nvarchar (tối đa) đủ lớn để được lưu trữ trong lưu trữ LOB.

Cuối tuần qua, tôi đã cố gắng xóa tất cả cùng một lúc. Nó chạy trong bốn giờ trước khi tôi hủy bỏ các truy vấn, sau đó nó được quay trở lại cho một 8 giờ - di chuyển xấu. Tôi thực sự không ngờ nó tệ đến thế.

Sau đó, tôi đã thử một cách tiếp cận khác. Gói này chạy vào ban đêm khi ứng dụng web xử lý khoảng 100 nghìn yêu cầu mỗi giờ. Trường Id tblJobs là một định danh duy nhất là khóa chính.

insert @tableIds select Id from dbo.tblJobs with(nolock) 
where (datediff(day, SchedDate, getDate()) > 60) 
    or (datediff(day, ModifiedDate, getDate()) > 3 and ToBeRemoved = 1) 

set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records count @tableIds: ' + convert(nvarchar(12), (select count(1) from @tableIds)) 
insert dbo.admin_MaintenanceLog(LogEntry) values(@maintLogStr) 

set @maintLogId = newid() 
set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records beginning loop...' 
insert dbo.admin_MaintenanceLog(Id, LogEntry) values(@maintLogId, @maintLogStr) 

while exists(select * from @tableIds) 
begin 
    delete @tableIdsTmp 
    begin transaction 
     insert @tableIdsTmp select top 1000 id from @tableIds 
     delete p from @tableIdsTmp i join dbo.tblJobs p on i.id = p.Id 
     delete x from @tableIdsTmp t join @tableIds x on t.id = x.id 
     set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records remaining count @tableIds: ' + convert(nvarchar(12), (select count(1) from @tableIds)) 
     update dbo.admin_MaintenanceLog set LogEntry = @maintLogStr, RecordCreated = getdate() where Id = @maintLogId 
    commit transaction 
    if @dowaits = 1 WAITFOR DELAY '00:00:01.000' 
end 

SchedDate, ModifiedDate và ToBeRemoved không được lập chỉ mục để thu thập các Id trong @tableIds mất khoảng 3 phút - không tệ.

Sau đó, từ các mục nhật ký, phải mất 1 giờ 55 phút để xóa 11.000 hồ sơ từ tblJobs lúc đó công việc được gọi là từ một máy từ xa timed out.

Tại sao mất quá nhiều thời gian? Tôi có thể làm gì để tăng tốc nó?

+0

Có một cơ sở dữ liệu hiệu suất cơ sở dữ liệu Azure SQL có thể giúp tôi với điều này không? – RJBreneman

+0

Bạn không đăng sự cố xóa – Paparazzi

Trả lời

0

CNTT phụ thuộc vào DTU (tầng hiệu suất) của cơ sở dữ liệu của bạn. Kiểm tra mức tiêu thụ tài nguyên của cơ sở dữ liệu trong thời gian thực hiện truy vấn để xem liệu bạn có đang gặp bất kỳ giới hạn tài nguyên nào không. Cũng trong tương lai, chia nhỏ truy vấn thành nhiều giao dịch trong khi phát hành xóa. Điều này giúp trong trường hợp giao dịch của bạn phải quay lại (ví dụ nâng cấp lên SQL DB) hoặc lỗi tạm thời của mạng từ đầu của bạn kết nối với db

+1

Cơ sở dữ liệu là tầng V12, S2. Biểu đồ tỷ lệ phần trăm DTU cho biết khoảng 95% trong thời gian này, không có thời gian mở rộng ở 100% - Tôi có cảnh báo trên> = 100% trong 5 phút chưa bao giờ được kích hoạt. Tôi không chắc chắn những gì bạn có nghĩa là bằng cách phá vỡ xóa thành nhiều giao dịch. Nó đang phát hành 1000 tại một thời điểm. – RJBreneman

0

Là giải pháp/hack nhanh chóng, trong SSMS tôi đã nhấp vào cơ sở dữ liệu và sau đó chọn Generate Scripts và trong các tùy chọn nâng cao, tôi đã chọn tạo các kịch bản lệnh DROP ONLY. Từ đó đặt điều đó trong cửa sổ truy vấn mới và tôi đã tìm và thay thế để thay đổi DROP TABLE thành DELETE FROM. Nó vẫn còn có một vài vấn đề đặt chúng theo thứ tự sai cho phụ thuộc chính của nước ngoài, nhưng sau một vài chỉnh sửa, tôi đã nhanh chóng có thể xóa tất cả các bảng của tôi.

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