统计信息(有助于决定是否使用索引)是否考虑每个实际列值的行数,还是仅使用平均值 每个值的行数。
假设我有一个表,其中有一个名为 active 的位列,其中有 100 万行,但 99.99% 设置为 false。如果我在该列上有索引,那么 Sql 是否足够聪明,知道在搜索 active=1 时使用索引,但在搜索 active=0 时则没有意义。
另一个例子,如果我有一个表,其中有 1,000,000 条记录,其中一个索引列包含大约 50,000 个不同的值,每个值的平均行数为 10,但有一个特殊值包含 500,000 行。如果搜索此特殊记录,该索引可能没有用,但在查找任何其他代码时将非常有用。
但是这种特殊情况会破坏索引的有效性吗?
最佳答案
你可以自己看看:
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'
在我看来,它总是使用此查询计划上的索引:
关于sql-server - SQL 统计信息和索引 - 它们有多详细?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3999288/