Hiệu suất máy chủ SQL xuống cấp đột ngột


13

Tôi có một SQL Server 2005 đã trở nên khó đoán trước và tôi đang gãi đầu về lý do. Các truy vấn được thực hiện trong vài giây đang thay đổi kế hoạch và mất vài phút (dành thời gian để quét toàn bộ bảng hoặc bộ đệm chỉ mục). Bây giờ, điều đầu tiên và rõ ràng nhất là, số liệu thống kê đã lỗi thời khiến trình tối ưu hóa bị lẫn lộn nhưng tôi tin rằng đây không phải là trường hợp - trước tiên là vì dữ liệu cơ bản không thay đổi đáng kể (ví dụ: thêm dữ liệu một ngày vào dữ liệu của một năm đã có trong một bảng) và thứ hai vì Thống kê tự động tạo và thống kê cập nhật tự động đều đúng. Tuy nhiên, trình tối ưu hóa đang bị lẫn lộn; việc chạy SQL trong Trình cố vấn điều chỉnh cung cấp cho tôi rất nhiều CREATE STATISTICScâu lệnh nhiều cột mà dường như để sửa nó (cho đến khi các lỗi tiếp theo của SQL xảy ra).

Bất kỳ ý tưởng về một chiến lược tôi có thể sử dụng để tiếp cận căn nguyên này? Bất kỳ lý do tại sao số liệu thống kê "bình thường" không đủ?

Câu trả lời:


8

Nếu chờ đợi hàng đầu của bạn là SOS_SCHEDULER_YIELD, thì có vẻ như bạn sẽ có một chút áp lực với CPU. Nhưng điều này có thể là kết quả của một cái gì đó khác, chẳng hạn như thiết kế của bạn không còn đủ cho các truy vấn của bạn. Tôi biết bạn nói rằng bạn chỉ thêm dữ liệu trong một ngày, nhưng bạn có thể đã đạt đến điểm bùng phát.

Làm thế nào là truy vấn của bạn được ban hành? Có phải là SQL động? Bạn đang sử dụng các thủ tục được lưu trữ? Bạn đang sử dụng sp_executesql? Có thể là bạn có một trường hợp đánh hơi tham số? Thiết kế db của bạn trông như thế nào? Mối quan hệ PK và FK là gì?

Bạn có một ví dụ về một kế hoạch tốt? Nếu bạn có thể xác định một kế hoạch tốt, bạn có thể sử dụng các hướng dẫn kế hoạch để buộc truy vấn thực hiện theo một cách cụ thể.

Bạn có thể đưa ra một ví dụ về một kế hoạch tốt xấu đi?

Cuối cùng, hãy lấy một bản sao của sp_whoIsActive ( http://whoisactive.com/ ) từ Adam Machanic và sử dụng bản đó để xác định thêm về các truy vấn đang chạy. Và nếu bạn muốn có thể chụp đầu ra từ sp_whoIsActive, hãy truy cập tại đây http://www.littlekendra.com/2011/02/01/whoisactive/


Đó là một ứng dụng của bên thứ ba, tôi không có quyền kiểm soát đối với lược đồ hoặc SQL của nó, điều này khá kinh khủng, rất nhiều truy vấn được tham số hóa (ví dụ where col=(cast @var...)) và @varcó thể '%'. Tôi mới thừa hưởng nó một hoặc hai tuần trước và cần giữ cho nó hoạt động cơ bản cho đến khi nó được thay thế. Cảm ơn vì liên kết, tôi sẽ cho nó một vòng xoáy.
Gaius

Tiếp chờ đợi nhất sau khi SOS_SCHEDULER_YIELDđã CXPACKETsp_configure "max degree of parallelism", 1dường như có - bây giờ - gõ cả hai vấn đề trên đầu. Cảm ơn!
Gaius

+1 cho liên kết đến sp_whoIsActive
Jeff

8

Từ MSDN :

" Thao tác chèn xảy ra trên các cột khóa tăng dần hoặc giảm dần Thống kê trên các cột khóa tăng dần hoặc giảm dần, chẳng hạn như cột IDENTITY hoặc cột thời gian thực, có thể yêu cầu cập nhật thống kê thường xuyên hơn so với trình tối ưu hóa truy vấn thực hiện. Số lượng hàng được thêm vào có thể quá ít để kích hoạt cập nhật thống kê. Nếu số liệu thống kê không cập nhật và các truy vấn được chọn từ các hàng được thêm gần đây nhất, số liệu thống kê hiện tại sẽ không có ước tính chính cho các giá trị mới này. dẫn đến ước tính cardinality không chính xác và hiệu suất truy vấn chậm.

Ví dụ: một truy vấn được chọn từ các ngày đặt hàng gần đây nhất sẽ có ước tính chính xác về số lượng thẻ nếu số liệu thống kê không được cập nhật để bao gồm các ước tính về số lượng thẻ cho các ngày đặt hàng gần nhất.

Sau các hoạt động bảo trì Xem xét cập nhật số liệu thống kê sau khi thực hiện các quy trình bảo trì thay đổi phân phối dữ liệu, chẳng hạn như cắt bớt bảng hoặc thực hiện chèn hàng loạt một tỷ lệ lớn các hàng. Điều này có thể tránh sự chậm trễ trong tương lai trong xử lý truy vấn trong khi các truy vấn chờ cập nhật thống kê tự động. "

Thỉnh thoảng bạn có thể sử dụng "EXEC sp_updatestats" trên hệ thống của mình (đã lên lịch) hoặc sử dụng chức năng STATS_DATE trên tất cả các đối tượng và xem khi nào số liệu thống kê của chúng thực sự được cập nhật lần trước và nếu có quá nhiều thời gian kể từ đó, hãy sử dụng CẬP NHẬT THỐNG KÊ cho đối tượng cụ thể đó. Theo kinh nghiệm của tôi, ngay cả khi thống kê Tự động được bật, chúng tôi vẫn buộc phải cập nhật thống kê theo thời gian, vì các hoạt động chèn không kích hoạt cập nhật tự động.

Để thêm mã cá nhân của tôi (được sử dụng trong công việc hàng tuần, xây dựng các báo cáo động để cập nhật thống kê):

select distinct
        'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
            + case when stats.RowCnt > 50000 then ' with sample 30 percent;'
            else 
                ';' end
        as UpdateStatement
    from (
        select
            ss.name SchemaName,
            so.name TableName,
            so.id ObjectId,
            st.name AS StatsName, 
            STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
            , si.RowModCtr
            , (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
        from sys.stats st
            join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
            join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
            join sys.schemas ss on ss.schema_id = so.uid
    ) stats
    where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
    or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
        datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
        and stats.RowCnt > 0
    )

Ở đây tôi nhận được tất cả các đối tượng không có số liệu thống kê được cập nhật trong hơn 3 tháng hoặc kể từ lần cập nhật thống kê cuối cùng, nó đã có hơn 10% số hàng thay đổi.


Hmm, sự kiện chờ đợi hàng đầu của tôi là SOS_SCHEDULER_YIELDnhưng tôi không thể biết ngay bây giờ nếu đó là do kế hoạch tồi, hay hộp này (6 tuổi, 2 bộ xử lý, RAM 4G) thực sự đã quá tải và tôi đã quá tải đã đi qua một số điểm tới hạn.
Gaius

thay vì chỉ chạy truy vấn đó để tạo các câu lệnh CẬP NHẬT và chạy chúng theo cách thủ công, bạn có thể sử dụng một con trỏ dựa trên câu lệnh chọn đó để lặp vòng kết quả chạy chúng bằng cách sử dụng các lệnh gọi đến sp_executesql - ví dụ như bạn có thể chạy nó một cách tự động của một kế hoạch bảo trì qua đêm (hoặc thời gian yên tĩnh khác).
David Spillett

@David: đây là những gì tôi đang làm trong công việc hàng tuần :). Tôi vừa định dạng nó cho Gaius để xem đầu ra tôi đang sử dụng. Kịch bản ban đầu quá xấu và dài. Cảm ơn sự giúp đỡ với định dạng! Bạn có thể gửi cho tôi một hướng dẫn định dạng không. Bởi vì tôi không thực sự biết cách làm cho mã trông đẹp ở đây. Cảm ơn!
Mary

có một liên kết "trợ giúp định dạng" trên màn hình "chỉnh sửa câu trả lời" và dưới dạng biểu tượng ở bên phải hộp trả lời ban đầu trên trang câu hỏi chính, liệt kê cú pháp đánh dấu được hỗ trợ bởi các trang web này.
David Spillett

3
Thống kê cập nhật tự động thực sự kích hoạt ở 20% + 500 hàng, không phải 10%.
mrdenny

3

Tôi đoán là một hoặc nhiều bảng của bạn đủ lớn để chúng không đạt 20% thay đổi cần thiết để đánh dấu số liệu thống kê hiện tại là cũ để Thống kê cập nhật tự động sẽ khởi động và vẫn có đủ cập nhật (hoặc chèn ) rằng có số liệu thống kê cập nhật sẽ giúp rất nhiều. Tôi đã tìm thấy điều tương tự gần đây trong một môi trường cụ thể sau khi nâng cấp từ SQL 2000 lên SQL 2008.

Ngoài các trang web khác được đề cập trong các câu trả lời ở trên, tôi sẽ đề nghị kiểm tra các tài nguyên trực tuyến sau.

1) Red-Gate có một số sách điện tử miễn phí có sẵn để tải xuống, bao gồm cả "Thống kê máy chủ SQL" của Holger Schmeling, nơi bạn sẽ tìm thấy trích dẫn sau:

http://www.red-gate.com/our-company/about/book-store/

"các bảng có hơn 500 hàng ít nhất 20% dữ liệu của một cột phải được thay đổi để làm mất hiệu lực mọi thống kê được liên kết"

2) SQL Sentry có một công cụ Plan Explorer miễn phí giúp theo dõi các vấn đề trong kế hoạch SQL, chẳng hạn như ước tính quá nhiều hoặc quá ít hàng so với số lượng hàng thực tế cho một bảng đã cho trong một truy vấn. Chỉ cần lưu kế hoạch thực hiện thực tế từ SSMS và sau đó đi qua các phần khác nhau của kế hoạch bằng Plan Explorer. Không phải là thông tin không có sẵn trong SSMS bằng cách sử dụng kế hoạch thực hiện đồ họa, nhưng công cụ từ SQL Sentry giúp dễ nhìn hơn nhiều.

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

3) Tự kiểm tra ngày cập nhật thống kê cho các bảng trong các truy vấn bạn quan tâm nhất khi sử dụng STATS_DATE (), bạn có thể tìm một truy vấn nhanh để lấy số liệu thống kê cũ nhất bằng cách sử dụng truy vấn được tìm thấy trong cuộc thảo luận sau.

http://blog.sqlauthority.com/2010/01/11/sql-server-find-statistic-update-date-update-statistic/

Tôi hi vọng cái này giúp được!

Tôi nghĩ bạn sẽ đặc biệt thích cuốn sách từ Red-Gate!

-Jeff


Cảm ơn, tôi sẽ làm việc theo cách của mình thông qua những điều đó. Tôi chủ yếu là một DBA của Oracle, người đã kế thừa hệ thống này (tho 'Tôi không thành kiến ​​với SQL Server, từ những gì tôi thấy từ năm 2005, đó là một nền tảng rất có khả năng, tôi chỉ không biết về nó cũng như tôi biết Oracle) .
Gaius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.