Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Một cách khác để xem cập nhật tự động cho thống kê

Vào tháng 4, tôi đã viết về một số phương pháp gốc trong SQL Server có thể được sử dụng để theo dõi các bản cập nhật tự động cho thống kê. Ba tùy chọn tôi đã cung cấp là Truy tìm SQL, Sự kiện mở rộng và ảnh chụp nhanh của sys.dm_db_stats_properties. Trong khi ba tùy chọn này vẫn khả thi (ngay cả trong SQL Server 2014, mặc dù khuyến nghị hàng đầu của tôi vẫn là XE), một tùy chọn bổ sung mà tôi nhận thấy khi chạy một số thử nghiệm gần đây là SQL Sentry Plan Explorer.

Nhiều người trong số các bạn sử dụng Plan Explorer chỉ đơn giản để đọc các kế hoạch đang thực thi, điều này thật tuyệt. Nó có rất nhiều lợi ích so với Management Studio khi xem xét các kế hoạch - từ những điều nhỏ nhặt, như có thể sắp xếp theo các nhà khai thác hàng đầu và dễ dàng xem các vấn đề ước tính bản số, đến những lợi ích lớn hơn, như xử lý các kế hoạch phức tạp và lớn và có thể chọn một tuyên bố trong một lô để xem xét kế hoạch dễ dàng hơn. Nhưng đằng sau hình ảnh trực quan giúp dễ dàng phân tích các kế hoạch, Plan Explorer cũng cung cấp khả năng thực hiện một truy vấn và xem kế hoạch thực tế (thay vì chạy nó trong Management Studio và lưu nó đi). Và trên hết, khi bạn chạy kế hoạch từ PE, có thêm thông tin được thu thập có thể hữu ích.

Hãy bắt đầu với bản demo mà tôi đã sử dụng trong bài đăng gần đây của mình, Cập nhật tự động cho thống kê có thể ảnh hưởng đến hiệu suất truy vấn như thế nào. Tôi bắt đầu với cơ sở dữ liệu AdventureWorks2012 và tôi đã tạo một bản sao của bảng SalesOrderHeader với hơn 200 triệu hàng. Bảng có chỉ mục được phân nhóm trên SalesOrderID và chỉ mục không được phân nhóm trên CustomerID, OrderDate, SubTotal. [Một lần nữa:nếu bạn định thực hiện các bài kiểm tra lặp lại, hãy sao lưu cơ sở dữ liệu này tại thời điểm này để tiết kiệm thời gian cho bản thân.] Trước tiên, tôi đã xác minh số hàng hiện tại trong bảng và số hàng cần thay đổi để gọi cập nhật tự động:

SELECT
OBJECT_NAME([p].[object_id]) [TableName],
[si].[name] [IndexName],
[au].[type_desc] [Type],
[p].[rows] [RowCount],
([p].[rows]*.20) + 500 [UpdateThreshold],
[au].total_pages [PageCount],
(([au].[total_pages]*8)/1024)/1024 [TotalGB]
FROM [sys].[partitions] [p]
JOIN [sys].[allocation_units] [au] ON [p].[partition_id] = [au].[container_id]
JOIN [sys].[indexes] [si] on [p].[object_id] = [si].object_id and [p].[index_id] = [si].[index_id]
WHERE [p].[object_id] = OBJECT_ID(N'Sales.Big_SalesOrderHeader');


Big_SalesOrderHeader Thông tin CIX và NCI

Tôi cũng đã xác minh tiêu đề thống kê hiện tại cho chỉ mục:

DBCC SHOW_STATISTICS ('Sales.Big_SalesOrderHeader',[IX_Big_SalesOrderHeader_CustomerID_OrderDate_SubTotal]);


Thống kê NCI:Lúc bắt đầu

Quy trình được lưu trữ mà tôi sử dụng để kiểm tra đã được tạo, nhưng để hoàn thiện, mã được liệt kê bên dưới:

CREATE PROCEDURE Sales.usp_GetCustomerStats
@CustomerID INT,
@StartDate DATETIME,
@EndDate DATETIME
AS
BEGIN
  SET NOCOUNT ON;
 
  SELECT CustomerID, DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate), COUNT([SalesOrderID]) as Computed
    FROM [Sales].[Big_SalesOrderHeader]
    WHERE CustomerID = @CustomerID
    AND OrderDate BETWEEN @StartDate and @EndDate
    GROUP BY CustomerID, DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate)
    ORDER BY DATEPART(YEAR, OrderDate), DATEPART(MONTH, OrderDate);
END

Trước đây, tôi đã bắt đầu phiên Theo dõi hoặc Sự kiện mở rộng hoặc thiết lập phương pháp của mình để chụp nhanh sys.dm_db_stats_properties vào một bảng. Đối với ví dụ này, tôi vừa chạy quy trình được lưu trữ ở trên một vài lần:

EXEC Sales.usp_GetCustomerStats 11331, '2012-08-01 00:00:00.000', '2012-08-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11330, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11506, '2012-11-01 00:00:00.000', '2012-11-30 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 17061, '2013-01-01 00:00:00.000', '2013-01-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 11711, '2013-03-01 00:00:00.000', '2013-03-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 15131, '2013-02-01 00:00:00.000', '2013-02-28 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 29837, '2012-10-01 00:00:00.000', '2012-10-31 23:59:59.997'
GO
EXEC Sales.usp_GetCustomerStats 15750, '2013-03-01 00:00:00.000', '2013-03-31 23:59:59.997'
GO

Sau đó, tôi đã kiểm tra bộ đệm thủ tục để xác minh số lượng thực thi và cũng xác minh kế hoạch đã được lưu trong bộ đệm:

SELECT
OBJECT_NAME([st].[objectid]),
[st].[text],
[qs].[execution_count],
[qs].[creation_time],
[qs].[last_execution_time],
[qs].[min_worker_time],
[qs].[max_worker_time],
[qs].[min_logical_reads],
[qs].[max_logical_reads],
[qs].[min_elapsed_time],
[qs].[max_elapsed_time],
[qp].[query_plan]
FROM [sys].[dm_exec_query_stats] [qs]
CROSS APPLY [sys].[dm_exec_sql_text]([qs].plan_handle) [st]
CROSS APPLY [sys].[dm_exec_query_plan]([qs].plan_handle) [qp]
WHERE [st].[text] LIKE '%usp_GetCustomerStats%'
AND OBJECT_NAME([st].[objectid]) IS NOT NULL;


Lập kế hoạch thông tin bộ nhớ cache cho SP:Lúc bắt đầu


Kế hoạch truy vấn cho thủ tục được lưu trữ, sử dụng SQL Sentry Plan Explorer

Kế hoạch được tạo vào 2014-09-29 23:23.01.

Tiếp theo, tôi thêm 61 triệu hàng vào bảng để làm mất hiệu lực thống kê hiện tại và sau khi quá trình chèn hoàn tất, tôi đã kiểm tra số lượng hàng:


Big_SalesOrderHeader Thông tin CIX và NCI:Sau khi chèn 61 triệu hàng

Trước khi chạy lại thủ tục đã lưu trữ, tôi đã xác minh rằng số lần thực thi không thay đổi, create_time vẫn là 2014-09-29 23:23.01 cho kế hoạch và thống kê đó chưa được cập nhật:


Lập kế hoạch thông tin bộ nhớ cache cho SP:Ngay sau khi chèn


Thống kê NCI:Sau khi chèn

Bây giờ, trong bài đăng trên blog trước, tôi đã chạy câu lệnh trong Management Studio, nhưng lần này, tôi chạy truy vấn trực tiếp từ Plan Explorer và nắm bắt được Kế hoạch thực tế qua PE (tùy chọn được khoanh đỏ trong hình ảnh bên dưới).


Thực thi quy trình được lưu trữ từ Plan Explorer

Khi bạn thực hiện một câu lệnh từ PE, bạn phải nhập cá thể và cơ sở dữ liệu mà bạn muốn kết nối, sau đó bạn được thông báo rằng truy vấn sẽ chạy và kế hoạch thực tế sẽ được trả về, nhưng kết quả sẽ không được trả về. Lưu ý rằng điều này khác với Management Studio, nơi bạn có thể nhìn thấy kết quả.

Sau khi tôi chạy thủ tục được lưu trữ, trong đầu ra, tôi không chỉ nhận được kế hoạch mà còn thấy những câu lệnh nào đã được thực thi:


Đầu ra kế hoạch Explorer sau khi thực thi SP (sau khi chèn)

Điều này khá tuyệt… ngoài việc xem câu lệnh được thực thi trong thủ tục được lưu trữ, tôi cũng thấy các cập nhật cho thống kê, giống như tôi đã làm khi nắm bắt các bản cập nhật bằng Sự kiện mở rộng hoặc SQL Trace. Cùng với việc thực thi câu lệnh, chúng ta cũng có thể xem thông tin CPU, thời lượng và IO. Bây giờ - thông báo trước ở đây là tôi có thể xem thông tin này nếu Tôi chạy câu lệnh gọi cập nhật thống kê từ Plan Explorer. Điều đó có thể sẽ không xảy ra thường xuyên trong môi trường sản xuất của bạn, nhưng bạn có thể thấy điều này khi thực hiện thử nghiệm (vì hy vọng thử nghiệm của bạn không chỉ liên quan đến việc chạy các truy vấn CHỌN mà còn liên quan đến các truy vấn CHÈN / CẬP NHẬT / XÓA giống như bạn sẽ làm xem trong một khối lượng công việc bình thường). Tuy nhiên, nếu bạn đang theo dõi môi trường của mình bằng một công cụ như SQL Sentry, bạn có thể thấy các bản cập nhật này trong SQL Top miễn là chúng vượt quá ngưỡng thu thập SQL hàng đầu. SQL Sentry có các ngưỡng mặc định mà các truy vấn phải vượt quá trước khi chúng được ghi lại dưới dạng SQL Top (ví dụ:thời lượng phải vượt quá năm (5) giây), nhưng bạn có thể thay đổi các ngưỡng đó và thêm các ngưỡng khác, chẳng hạn như lần đọc. Trong ví dụ này, chỉ dành cho mục đích thử nghiệm , Tôi đã thay đổi ngưỡng thời lượng tối thiểu Top SQL của mình thành 10 mili giây và ngưỡng đọc của tôi thành 500 và SQL Sentry có thể nắm bắt một số cập nhật thống kê:


Cập nhật thống kê được SQL Sentry thu thập

Điều đó nói rằng, việc giám sát có thể nắm bắt được những sự kiện này hay không cuối cùng sẽ phụ thuộc vào tài nguyên hệ thống và lượng dữ liệu phải đọc để cập nhật thống kê. Cập nhật thống kê của bạn không được vượt quá các ngưỡng này, vì vậy, bạn có thể phải chủ động đào sâu hơn để tìm chúng.

Tóm tắt

Tôi luôn khuyến khích các DBA chủ động quản lý số liệu thống kê - có nghĩa là cần có công việc để cập nhật số liệu thống kê một cách thường xuyên. Tuy nhiên, ngay cả khi công việc đó chạy hàng đêm (điều mà tôi không nhất thiết phải đề xuất), vẫn có khả năng xảy ra tự động cập nhật số liệu thống kê suốt cả ngày, bởi vì một số bảng có nhiều biến động hơn những bảng khác và có số lượng sửa đổi cao. Điều này không có gì bất thường và tùy thuộc vào kích thước của bảng và số lượng sửa đổi, các bản cập nhật tự động có thể không can thiệp đáng kể vào các truy vấn của người dùng. Nhưng cách duy nhất để biết là theo dõi những cập nhật đó - cho dù bạn đang sử dụng công cụ gốc hay công cụ của bên thứ ba - để bạn có thể biết trước các vấn đề tiềm ẩn và giải quyết chúng trước khi chúng leo thang.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng Jenkins với Kubernetes AWS, Phần 2

  2. Tìm hiểu cách sử dụng câu lệnh CASE trong SQL

  3. Kế hoạch thực thi Tác động đến ASYNC_NETWORK_IO Chờ - Phần 1

  4. Alibaba Cloud

  5. SQL CHỌN TỐI ĐA