Có thể xảy ra việc một lượng nhỏ dữ liệu đạt đến một giới hạn nhất định trong Máy chủ SQL để buộc một kế hoạch khác hoặc một cái gì đó tương tự. Điều này không phải là không thể. Nhưng thực tế là đĩa của bạn dường như đang chịu trách nhiệm nặng nề đưa tôi đến một kết luận khác.
Có 2 lý do cơ bản có thể khiến bạn chậm lại.
- Bạn đã nâng cấp hệ thống của mình và khởi động lại nó
- Bạn tải một loạt dữ liệu trong đó
Hãy xem phần 1
Có thể cấu hình SQL Server của bạn có thể bị hỏng. Điều này có thể gây ra vấn đề nghiêm trọng liên quan đến tốc độ Máy chủ của bạn và việc sử dụng đĩa.
Vui lòng kiểm tra trong trường hợp đầu tiên cài đặt máy chủ cơ bản của bạn. Những thiết lập cơ bản là max server memory
, affinity I/O mask
, affinity mask
và max degree of parallelism
. Bạn có thể cần phải kích hoạt các tùy chọn nâng cao bằng cách sử dụng show advanced options
.
Đây là một kịch bản hoàn chỉnh:
-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'
So sánh kết quả với các giá trị tài liệu của bạn trong các bước cài đặt của bạn. Họ vẫn giống nhau chứ?
Nó có thể có nhiều lý do tại sao máy chủ của bạn hoạt động rất lạ. Tôi thường đặt cược, rằng bạn max server memory
chỉ sai. Điều này sẽ khiến SQL Server của bạn hoán đổi vĩnh viễn các trang dữ liệu. Anh ta không thể giữ mọi thứ trong trí nhớ của mình. Điều này có nghĩa là anh ta cần phải đọc các trang từ đĩa, cập nhật nó, viết lại ngay lập tức. Nếu một bản cập nhật khác xuất hiện và sử dụng cùng một trang cho một bản cập nhật, nó không thể được đọc từ bộ nhớ. Thay vào đó, máy chủ cần đọc lại từ đĩa. Chỉ cần hoán đổi ...
Một vấn đề khác có thể là mối quan hệ cao đến đĩa hoặc quá trình. Nếu bạn đã sử dụng Máy chủ dùng chung (Máy chủ SQL + các dịch vụ khác) với đĩa dành riêng cho Máy chủ SQL (có thể là trường hợp hiếm gặp, nhưng có thể như vậy), đây có thể là vấn đề của bạn. Máy chủ của bạn thường được sử dụng để có 3 ví dụ cho các quy trình và một cho I / O. 12 cpus khác được sử dụng cho các dịch vụ khác. Trong trường hợp này, mặt nạ ái lực của bạn sai và sử dụng ví dụ cấu hình tự động. Điều này có nghĩa là Máy chủ của bạn sử dụng tất cả 16 lõi cho các quy trình và I / O một cách linh hoạt. Nếu bạn có các tiến trình lớn đang chạy, chúng có thể đặt một tải rất lớn lên đĩa mà nó có thể không xử lý được. Nhưng trên thực tế, tôi không tin rằng đây là trường hợp của bạn. Nó sẽ nhanh hơn (ngay cả khi chỉ một chút) nếu điều này được áp dụng, nhưng trường hợp của bạn là chậm lại.
Một vấn đề khác có thể là mức độ song song quá cao. Điều đó có nghĩa là bạn có quá nhiều luồng không hoạt động trên một phần của truy vấn. Điều này cũng có thể gây ra sự chậm lại rất lớn nếu song song không hoạt động như mong đợi. Nhưng điều này sẽ không mô tả tổng số I / O cao của bạn.
Bây giờ chúng ta hãy xem phần 2
Bạn tải một loạt các hàng vào hệ thống của bạn. Ngay cả khi đây là một công việc thông thường, nó có thể đưa ra một giới hạn trong đó các kế hoạch truy vấn của bạn leo thang. Thậm chí có thể là trường hợp chèn của bạn kết hợp với SQL Server tạo ra hành vi này.
Bạn đã đề cập rằng bạn đã cố gắng di chuyển các chỉ số của mình sang một đĩa khác, điều này có vẻ hữu ích. Điều này có thể xảy ra chỉ với thực tế là bạn chia tải trên hai đĩa khác nhau.
Nó có thể là các chỉ số của bạn đã bị phá vỡ, kế hoạch của bạn đã bị phá vỡ hoặc số liệu thống kê của bạn đã lỗi thời.
1. cho phép kiểm tra số liệu thống kê cập nhật mới nhất
Bạn có thể thực hiện thủ công qua giao diện cho từng yếu tố thống kê. Đó sẽ là một nỗi đau. Hoặc bạn có thể thử mã này:
SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
Điều này sẽ cung cấp cho bạn một thông tin đầy đủ qua từng chỉ số (và heap) và số liệu thống kê đằng sau chúng. Ngay cả khi bạn chạy, điều sp_updatestats
đó không có nghĩa là số liệu thống kê đã được cập nhật. Phần khi cập nhật khá phức tạp, ngay cả khi bạn chạy sp_updatestats
hoặc ngay cả khi auto update statistics
được bật, số liệu thống kê sẽ không được cập nhật kịp thời. Dưới đây là một số điểm cạnh, khi cần cập nhật / tạo:
- Một bảng trống được một hoặc nhiều hàng
- Một bảng có hơn 500 hàng cập nhật 20% + 500 hàng bổ sung và một lần chèn đã xảy ra sau đó
- Khi 500 hàng được thay đổi trong một bảng chứa ít hơn 500 hàng
Điều này có nghĩa, số liệu thống kê của bạn có thể bị lỗi thời ngay cả khi bạn chạy bản cập nhật.
Bạn có thể xem các truy vấn ở trên. Nếu bạn tìm thấy một số thống kê khá cũ trong một số bảng, bạn có thể muốn chạy cập nhật thống kê thủ công cho bảng này:
UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN
Sau đó, bạn có thể muốn cho máy chủ của mình một cú đá vào mông để vứt bỏ tất cả các kế hoạch cũ.
DBCC FREEPROCCACHE
Nếu bạn chỉ muốn xóa tất cả bộ nhớ cache, bạn có thể muốn chạy cái này thay thế:
DBCC FREESYSTEMCACHE ('ALL')
Điều này sẽ dọn sạch tất cả bộ nhớ cache, không chỉ bộ nhớ cache của gói. Tôi thường cảnh báo, để sử dụng điều này trên một máy chủ sản xuất trong giai đoạn sản xuất. Nhưng vì máy chủ của bạn hiện không hoạt động, bạn không thể làm hại họ quá nhiều. Nó có thể chậm lại trong vài giây có thể 1-2 phút vì anh ta cần xây dựng lại tất cả các bộ nhớ cache, nhưng sau đó anh ta nên chạy với các kế hoạch chính xác.
Một lý do khác có thể là các chỉ số hoàn toàn bị phân mảnh. Điều này có thể được kiểm tra trên toàn bộ máy chủ bằng cách sử dụng câu lệnh này:
SELECT *
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)
Nếu sự phân mảnh rất cao, bạn có thể cần phải sắp xếp lại (phân mảnh <20%) hoặc xây dựng lại hoàn toàn (> 20%) nó. Điều này có thể gây áp lực nhiều hơn cho đĩa của bạn và gây rắc rối. Mặt khác, nếu các chỉ số đó là xấu, có lẽ nó sẽ giúp ích nhiều hơn là có hại.
Bên cạnh hai lý do đó, vẫn có thể có một vấn đề thứ ba
Có lẽ máy chủ của bạn được cấu hình có thể, bạn đã không thay đổi bất kỳ mã nào trong thời gian này, chỉ cần thêm một vài hàng. Tất cả các số liệu thống kê được cập nhật và tất cả các bộ nhớ cache được xây dựng lại. Tất cả các chỉ số của bạn được sắp xếp lại theo cách bạn cần, nhưng vẫn vậy - không có gì hoạt động. Nó chỉ có thể là bạn đã đạt đến giới hạn của bộ nhớ có sẵn trong các quy trình của bạn. Có lẽ bạn cần nhiều hơn. Bạn có thể chỉ cần kiểm tra nếu có bất kỳ quá trình nào cố gắng để có được nhiều bộ nhớ hơn bạn có.
Bạn có thể kiểm tra điều này bằng lệnh này:
SELECT * FROM sys.dm_exec_query_memory_grants
Nó sẽ cung cấp cho bạn một danh sách tất cả các phiên sử dụng bộ nhớ. Có thể có một số truy vấn vẫn đang chờ để lấy bộ nhớ. Những truy vấn có thể dễ dàng được lọc. Tất cả các phiên ở đâu granted_memory_kb IS NULL
. Đây là những phiên yêu cầu bộ nhớ nhưng không có được nó. Một điều nữa có thể là một bộ nhớ được cấp có thể thấp. Bạn có thể so sánh các cột requested_memory_kb
với granted_memory_kb
. Yêu cầu hiển thị bao nhiêu bộ nhớ mà quá trình cần để chạy tối ưu trong khi được cấp sẽ hiển thị bộ nhớ được kích hoạt cho quy trình. Nếu một tiến trình cần 2GB để chạy nhưng chỉ nhận được 2 MB ... bạn có thể tự mình lấy nó. ;-)
Một cách khác là kiểm tra RESSOURCE_SEMAPHORE
:
SELECT * FROM sys.dm_exec_query_resource_semaphore
Bạn có thể nhìn vào waiter_count
và grantee_count
. Nếu người phục vụ trên 0, bạn có áp lực lên bộ nhớ của mình, điều này có thể gây ra sự tráo đổi và có thể gây ra áp lực đĩa mà bạn nhìn thấy trong perfmon.