2010-10-22 46 views
5

Thực hiện thống kê (giúp quyết định liệu chỉ mục có được sử dụng) có tính đến số hàng trên giá trị cột thực tế hay không. Chỉ sử dụng số hàng trung bình .Thống kê và chỉ mục SQL - Chi tiết là gì?

Giả sử tôi có một bảng có một cột bit được gọi là hoạt động có hàng triệu hàng, nhưng với 99,99% được đặt thành false. Nếu tôi có một chỉ số trên cột này, thì Sql đủ thông minh để biết sử dụng chỉ mục nếu tìm kiếm active = 1 nhưng không có điểm nếu tìm kiếm active = 0.

Ví dụ khác, nếu tôi có bảng có 1.000.000 bản ghi với cột được lập chỉ mục chứa khoảng 50.000 giá trị khác nhau với số hàng trung bình trên mỗi giá trị 10, nhưng sau đó một giá trị đặc biệt có 500.000 hàng. Chỉ mục có thể không hữu ích nếu tìm kiếm bản ghi đặc biệt này, nhưng sẽ rất hữu ích khi tìm kiếm bất kỳ mã nào khác.

Nhưng trường hợp đặc biệt này có làm hỏng hiệu quả của chỉ mục hay không.

Trả lời

1

Nó tạo ra một biểu đồ và do đó sẽ sử dụng nó.

Với một cột chút nó sẽ có một ý tưởng tốt bao nhiêu là 0 và 1

Với một cột chuỗi, nó iwll có một ý tưởng sơ bộ "ban nhạc" (giá trị bắt đầu từ a, b, c, vv) . Tương tự cho các con số (nó tạo ra x dải giá trị).

Chỉ cần tra cứu số liệu thống kê trông như thế nào trong studio quản lý của bạn - bạn thực sự có thể truy cập biểu đồ.

3

Bạn có thể xem cho chính mình:

CREATE TABLE IndexTest (
Id int not null primary key identity(1,1), 
Active bit not null default(0), 
IndexedValue nvarchar(10) not null 
) 

CREATE INDEX IndexTestActive ON IndexTest (Active) 
CREATE INDEX IndexTestIndexedValue ON IndexTest (IndexedValue) 

DECLARE @values table 
(
    Id int primary key IDENTITY(1, 1), 
    Value nvarchar(10) 
) 

INSERT INTO @values(Value) VALUES ('1') 
INSERT INTO @values(Value) VALUES ('2') 
INSERT INTO @values(Value) VALUES ('3') 
INSERT INTO @values(Value) VALUES ('4') 
INSERT INTO @values(Value) VALUES ('5') 
INSERT INTO @values(Value) VALUES ('Many') 
INSERT INTO @values(Value) VALUES ('Many') 
INSERT INTO @values(Value) VALUES ('Many') 
INSERT INTO @values(Value) VALUES ('Many') 
INSERT INTO @values(Value) VALUES ('Many') 

DECLARE @rowCount int 
SET @rowCount = 100000 

WHILE(@rowCount > 0) 
BEGIN 
    DECLARE @valueIndex int 
    SET @valueIndex = CAST(RAND() * 10 + 1 as int) 
    DECLARE @selectedValue nvarchar(10) 
    SELECT @selectedValue = Value FROM @values WHERE Id = @valueIndex 
    DECLARE @isActive bit 
    SELECT @isActive = CASE 
      WHEN RAND() < 0.001 THEN 1 
      ELSE 0 
      END 
    INSERT INTO IndexTest(Active, IndexedValue) VALUES (@isActive, @selectedValue) 
    SET @rowCount = @rowCount - 1 
END 

SELECT count(*) FROM IndexTest WHERE Active = 1 
SELECT count(*) FROM IndexTest WHERE Active = 0 

SELECT count(*) FROM IndexTest WHERE IndexedValue = '1' 
SELECT count(*) FROM IndexTest WHERE IndexedValue = 'Many' 

Có vẻ với tôi như nó luôn luôn sử dụng các chỉ số về kế hoạch truy vấn này:

query plan

+0

Cảm ơn. Điều này có ích. Nếu tôi sử dụng nơi Active = 0 và IndexedValue = '1' nó sẽ thực hiện quét bảng trong khi Active = 1 và IndexValue = '1' sẽ sử dụng chỉ mục. – sgmoore

+0

Không phải là một thử nghiệm rất tốt. Bạn nên sử dụng 'SELECT *' vì dĩ nhiên nó sẽ luôn sử dụng chỉ mục cho 'COUNT (*)' –

1

Bạn chỉ có thể nhìn vào số liệu thống kê và xem cho chính mình :) DBCC SHOW_STATISTICS. Xem phần chú thích, nó có một lời giải thích tốt về cách thức biểu đồ đang thực sự được lưu trữ và sử dụng:

Để tạo biểu đồ, truy vấn ưu sắp xếp các giá trị cột, tính số lượng các giá trị mà phù hợp với từng giá trị cột riêng biệt và sau đó tổng hợp các giá trị cột thành tối đa 200 biểu đồ liền kề bước. Mỗi bước bao gồm một loạt các giá trị cột theo sau là giá trị cột được gắn trên. Phạm vi bao gồm tất cả các giá trị cột có thể có giữa các giá trị ranh giới , ngoại trừ chính các giá trị ranh giới . Giá trị thấp nhất của các giá trị cột được sắp xếp là giá trị biên trên của cho bước đầu tiên.

alt text

Đối với mỗi bước histogram:

  • dòng Bold đại diện cho giá trị trên ranh giới (RANGE_HI_KEY) và số lần nó xảy ra (EQ_ROWS)
  • khu vực rắn bên trái RANGE_HI_KEY đại diện cho phạm vi giá trị cột và số lần trung bình mỗi col giá trị umn xảy ra (AVG_RANGE_ROWS). Các AVG_RANGE_ROWS cho bước histogram đầu tiên luôn luôn là 0.
  • đường chấm đại diện cho các giá trị lấy mẫu sử dụng để ước tính tổng số giá trị khác biệt trong khoảng (DISTINCT_RANGE_ROWS) và tổng số các giá trị trong khoảng (RANGE_ROWS) . Trình tối ưu hóa truy vấn sử dụng RANGE_ROWS và DISTINCT_RANGE_ROWS để tính AVG_RANGE_ROWS và không lưu trữ các giá trị được lấy mẫu .

Trình tối ưu hóa truy vấn xác định các bước biểu đồ theo ý nghĩa thống kê của chúng. Nó sử dụng thuật toán chênh lệch tối đa để giảm thiểu số bước trong biểu đồ trong khi tối đa hóa chênh lệch giữa giá trị ranh giới . Số bước tối đa là 200. Số lượng các bước biểu đồ có thể nhỏ hơn số giá trị riêng biệt, ngay cả đối với các cột có ít hơn hơn 200 điểm ranh giới. Ví dụ: cột có 100 giá trị khác nhau có thể có biểu đồ có ít hơn 100 điểm ranh giới.