2012-10-23 45 views
7

Tôi có một bảng gồm hơn 1 tỷ hàng dữ liệu chuỗi thời gian với hiệu suất chèn tuyệt vời nhưng (đôi khi) hiệu suất chọn khủng khiếp.Máy chủ SQL: hiệu suất dữ liệu chuỗi thời gian

Bảng tblTrendDetails (PK được ra lệnh như hình):

PK TrendTime datetime 
PK CavityId  int 
PK TrendValueId int 
    TrendValue real 

Bảng này được liên tục kéo trong dữ liệu mới và thanh lọc dữ liệu cũ, vì vậy chèn và xóa hiệu suất cần để duy trì snappy.

Khi thực hiện một truy vấn như sau, hiệu suất là nghèo (30 giây):

SELECT * 
FROM tblTrendDetails 
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime 
    AND CavityId = @inCavityId 
    AND TrendValueId = @inTrendId 

Nếu tôi thực hiện cùng một truy vấn một lần nữa (với thời gian tương tự, nhưng bất kỳ @inCavityId hoặc @inTrendId), hiệu suất là rất tốt (1 giây) Bộ đếm hiệu suất cho thấy rằng truy cập đĩa là thủ phạm lần đầu tiên truy vấn được chạy.

Bất kỳ đề xuất nào về cách cải thiện hiệu suất mà không (đáng kể) ảnh hưởng xấu đến hiệu suất chèn hoặc xóa? Bất kỳ đề xuất nào (bao gồm thay đổi hoàn toàn cơ sở dữ liệu cơ bản) đều được hoan nghênh.

+1

PK có được nhóm không? Bất kỳ chỉ mục nào? –

+1

@TimLehner Có .. PK được nhóm lại. Không có (khác) chỉ mục. – pilotcam

Trả lời

6

Thực tế là các truy vấn tiếp theo của cùng một dữ liệu hoặc dữ liệu tương tự chạy nhanh hơn nhiều có thể do SQL Server caching your data. Điều đó nói rằng, có thể tăng tốc truy vấn ban đầu này lên không?

Xác minh kế hoạch truy vấn:

tôi đoán là truy vấn của bạn nên kết quả trong một Index Tìm kiếm chứ không phải là một Scan Index (hoặc tệ hơn, một Quét Bảng). Vui lòng xác minh điều này bằng cách sử dụng SET SHOWPLAN_TEXT ON; hoặc một tính năng tương tự. Sử dụng between= làm truy vấn của bạn thực sự phải là take advantage of the clustered index, mặc dù that's debatable.

Index Phân mảnh:

Có thể là nhóm chỉ số của bạn (khóa chính trong trường hợp này) là khá rời rạc sau khi tất cả những chèn và xóa dần. Tôi có lẽ sẽ kiểm tra điều này với DBCC SHOWCONTIG (tblTrendDetails).

Bạn có thể chống phân mảnh chỉ mục của bảng bằng DBCC INDEXDEFRAG (MyDatabase, tblTrendDetails). Quá trình này có thể mất một chút thời gian, nhưng sẽ cho phép bảng vẫn có thể truy cập được và bạn có thể ngừng hoạt động mà không có bất kỳ tác dụng phụ khó chịu nào.

Bạn có thể phải đi xa hơn và sử dụng DBCC DBREINDEX (tblTrendDetails). Tuy nhiên, đây là một hoạt động ngoại tuyến, vì vậy bạn chỉ nên thực hiện điều này khi không cần truy cập vào bảng.

Có một số khác biệt được mô tả tại đây: Microsoft SQL Server 2000 Index Defragmentation Best Practices.

Lưu ý rằng nhật ký giao dịch của bạn có thể phát triển một chút từ việc chống phân mảnh một bảng lớn và có thể mất nhiều thời gian.

xem phân vùng:

Nếu những không khắc phục tình hình (hoặc phân mảnh không phải là một vấn đề), bạn thậm chí có thể muốn nhìn vào partitioned views, trong đó bạn tạo ra một loạt các bảng cơ sở cơ bản cho nhiều phạm vi của các bản ghi, sau đó kết hợp tất cả chúng trong một khung nhìn (thay thế bảng gốc của bạn).

Better Stuff:

Nếu hiệu suất của những Selects là một nhu cầu kinh doanh thực sự, bạn có thể làm cho trường hợp cho phần cứng tốt hơn: ổ đĩa nhanh hơn, bộ nhớ nhiều hơn, vv Nếu ổ đĩa của bạn là gấp đôi nhanh, sau đó truy vấn này sẽ chạy trong một nửa thời gian, phải không? Ngoài ra, điều này có thể không khả thi đối với bạn, nhưng tôi đã tìm thấy các phiên bản SQL Server mới hơn để thực sự nhanh hơn với nhiều tùy chọn hơn và tốt hơn để duy trì. Tôi rất vui vì đã chuyển hầu hết dữ liệu của công ty tôi sang 2008R2. Nhưng tôi digress ...

+2

+1 cho câu trả lời rất kỹ lưỡng và được nêu rõ. Tôi đã nhận được thông qua việc xác minh kế hoạch truy vấn trước khi đăng câu hỏi. Nhưng tôi không nghĩ về phân mảnh chỉ mục. Các 'SHOWCONTIG' chắc chắn tiết lộ phân mảnh. Tôi hiện đang chạy 'INDEXDEFRAG'. – pilotcam

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