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

Thống kê gia tăng SQL Server 2014

Benjamin Nevarez là một nhà tư vấn độc lập có trụ sở tại Los Angeles, California, người chuyên về điều chỉnh và tối ưu hóa truy vấn SQL Server. Ông là tác giả của “SQL Server 2014 Query Tuning &Optimization” và “Inside the SQL Server Query Optimizer” và là đồng tác giả của “SQL Server 2012 Internals”. Với hơn 20 năm kinh nghiệm trong lĩnh vực cơ sở dữ liệu quan hệ, Benjamin cũng là diễn giả tại nhiều hội nghị SQL Server, bao gồm PASS Summit, SQL Server Connections và SQLBits. Có thể tìm thấy blog của Benjamin tại http://www.benjaminnevarez.com và bạn cũng có thể liên hệ với anh ấy qua e-mail tại quản trị viên tại benjaminnevarez dot com và trên twitter tại @BenjaminNevarez.

Một vấn đề lớn với việc cập nhật thống kê trong các bảng lớn trong SQL Server là toàn bộ bảng luôn phải được quét, ví dụ:khi sử dụng WITH FULLSCAN tùy chọn, ngay cả khi chỉ có dữ liệu gần đây đã thay đổi. Điều này cũng đúng khi sử dụng phân vùng:ngay cả khi chỉ phân vùng mới nhất đã thay đổi kể từ lần cuối cùng thống kê được cập nhật, việc cập nhật lại thống kê vẫn cần thiết để quét toàn bộ bảng bao gồm tất cả các phân vùng không thay đổi. Số liệu thống kê tăng dần, một tính năng mới của SQL Server 2014, có thể giúp giải quyết vấn đề này.

Sử dụng thống kê gia tăng, bạn chỉ có thể cập nhật phân vùng hoặc các phân vùng mà bạn cần và thông tin trên các phân vùng này sẽ được hợp nhất với thông tin hiện có để tạo đối tượng thống kê cuối cùng. Một ưu điểm khác của thống kê gia tăng là tỷ lệ thay đổi dữ liệu cần thiết để kích hoạt cập nhật thống kê tự động hiện hoạt động ở cấp phân vùng, về cơ bản có nghĩa là bây giờ chỉ cần 20% số hàng thay đổi (thay đổi trên cột thống kê hàng đầu) trên mỗi phân vùng. Rất tiếc, biểu đồ vẫn bị giới hạn ở 200 bước cho toàn bộ đối tượng thống kê trong phiên bản SQL Server này.

Hãy để chúng tôi xem xét một ví dụ về cách bạn có thể cập nhật số liệu thống kê ở cấp phân vùng để khám phá hành vi của nó ít nhất kể từ SQL Server 2014 CTP2. Trước tiên, chúng ta cần tạo một bảng được phân vùng bằng cơ sở dữ liệu AdventureWorks2012:

CREATE PARTITION FUNCTION TransactionRangePF1 (DATETIME)
AS RANGE RIGHT FOR VALUES 
(
   '20071001', '20071101', '20071201', '20080101', 
   '20080201', '20080301', '20080401', '20080501', 
   '20080601', '20080701', '20080801'
);
GO
 
CREATE PARTITION SCHEME TransactionsPS1 AS PARTITION TransactionRangePF1 TO 
(
  [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], 
  [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], 
  [PRIMARY], [PRIMARY], [PRIMARY]
);
GO
 
CREATE TABLE dbo.TransactionHistory 
(
  TransactionID        INT      NOT NULL, -- not bothering with IDENTITY here
  ProductID            INT      NOT NULL,
  ReferenceOrderID     INT      NOT NULL,
  ReferenceOrderLineID INT      NOT NULL DEFAULT (0),
  TransactionDate      DATETIME NOT NULL DEFAULT (GETDATE()),
  TransactionType      NCHAR(1) NOT NULL,
  Quantity             INT      NOT NULL,
  ActualCost           MONEY    NOT NULL,
  ModifiedDate         DATETIME NOT NULL DEFAULT (GETDATE()),
  CONSTRAINT CK_TransactionType 
    CHECK (UPPER(TransactionType) IN (N'W', N'S', N'P'))
) 
ON TransactionsPS1 (TransactionDate);
GO

Lưu ý:Để biết chi tiết về phân vùng và CREATE PARTITION FUNCTION / SCHEME vui lòng tham khảo Bảng phân vùng và Chỉ mục trong Sách Trực tuyến.

Chúng tôi hiện có dữ liệu để điền 12 phân vùng. Chúng ta hãy bắt đầu bằng cách chỉ điền 11.

INSERT INTO dbo.TransactionHistory
SELECT * FROM Production.TransactionHistory
WHERE TransactionDate < '2008-08-01';

Nếu được yêu cầu, bạn có thể sử dụng câu lệnh sau để kiểm tra nội dung của các phân vùng:

SELECT * FROM sys.partitions
  WHERE object_id = OBJECT_ID('dbo.TransactionHistory');

Hãy để chúng tôi tạo một đối tượng thống kê tăng dần bằng cách sử dụng CREATE STATISTICS câu lệnh với INCREMENTAL mới mệnh đề được đặt thành ON (OFF là mặc định):

CREATE STATISTICS incrstats ON dbo.TransactionHistory(TransactionDate) 
  WITH FULLSCAN, INCREMENTAL = ON;

Bạn cũng có thể tạo thống kê gia tăng trong khi tạo chỉ mục bằng STATISTICS_INCREMENTAL mới mệnh đề của CREATE INDEX tuyên bố.

Bạn có thể kiểm tra đối tượng thống kê đã tạo bằng cách sử dụng DBCC :

DBCC SHOW_STATISTICS('dbo.TransactionHistory', incrstats);

Trong số những thứ khác, bạn sẽ nhận thấy rằng biểu đồ có 200 bước (chỉ 3 bước cuối cùng được hiển thị ở đây):

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS
198 2008-07-25 00:00:00.000 187 100 2
199 2008-07-27 00:00:00.000 103 101 1
200 2008-07-31 00:00:00.000 281 131 3

Kết quả DBCC ban đầu

Vì vậy, chúng tôi đã có tối đa các bước trong một đối tượng thống kê. Điều gì sẽ xảy ra nếu bạn thêm dữ liệu vào một phân vùng mới? Hãy để chúng tôi thêm dữ liệu vào phân vùng 12:

INSERT INTO dbo.TransactionHistory 
SELECT * FROM Production.TransactionHistory 
WHERE TransactionDate >= '2008-08-01';

Bây giờ, chúng tôi cập nhật đối tượng thống kê bằng cách sử dụng câu lệnh sau:

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH RESAMPLE ON PARTITIONS(12);

Lưu ý cú pháp mới chỉ định phân vùng, nơi bạn có thể chỉ định nhiều phân vùng, được phân tách bằng dấu phẩy. UPDATE STATISTICS câu lệnh đọc các phân vùng được chỉ định và sau đó hợp nhất kết quả của chúng với đối tượng thống kê hiện có để xây dựng thống kê toàn cục. Lưu ý RESAMPLE mệnh đề; điều này là bắt buộc vì thống kê phân vùng cần có cùng tỷ lệ mẫu được hợp nhất để xây dựng thống kê toàn cầu. Mặc dù chỉ quét phân vùng được chỉ định, bạn có thể thấy rằng SQL Server đã sắp xếp lại biểu đồ. Ba bước cuối cùng hiện hiển thị dữ liệu cho phân vùng đã thêm. Bạn cũng có thể so sánh biểu đồ gốc với biểu đồ mới để biết những khác biệt nhỏ khác:

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS
197 2008-07-31 00:00:00.000 150 131 2
198 2008-08-12 00:00:00.000 300 36 9
199 2008-08-22 00:00:00.000 229 43 7
200 2008-09-03 00:00:00.000 363 37 11

Kết quả DBCC sau khi cập nhật gia tăng

Nếu vì bất kỳ lý do gì bạn muốn tắt thống kê gia tăng, bạn có thể sử dụng câu lệnh sau để quay lại hành vi ban đầu (hoặc tùy chọn chỉ cần thả đối tượng thống kê và tạo một đối tượng mới).

UPDATE STATISTICS dbo.TransactionHistory(incrstats) 
  WITH FULLSCAN, INCREMENTAL = OFF;

Sau khi vô hiệu hóa số liệu thống kê gia tăng, cố gắng cập nhật một phân vùng như được hiển thị trước đó sẽ trả về thông báo lỗi sau:

Msg 9111, Mức 16, Trạng thái 1
CẬP NHẬT THỐNG KÊ TRÊN CÁC PHẦN Cú pháp không được hỗ trợ cho các thống kê không gia tăng.

Cuối cùng, bạn cũng có thể bật thống kê gia tăng cho thống kê tự động của mình ở cấp cơ sở dữ liệu, nếu cần. Điều này yêu cầu INCREMENTAL = ON trong ALTER DATABASE và rõ ràng cũng yêu cầu AUTO_CREATE_STATISTICS đặt thành ON .


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách ánh xạ nhiều phân vùng thành một nhóm tệp trong SQL Server (T-SQL)

  2. Có bất kỳ công cụ miễn phí nào để tạo tập lệnh 'CHÈN VÀO' trong MS SQL Server không?

  3. Thực thi sp_msforeachdb trong ứng dụng Java

  4. STRING_SPLIT () trong SQL Server 2016:Tiếp theo # 2

  5. Biểu thức chính quy trong máy chủ SQL Server?