Невозможно УДАЛИТЬ индекс, потому что это не сбор статистики - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь выполнить эту команду в Sql Server Management Studio:

DROP STATISTICS dbo.TableName.StatsName

Но я получаю эту ошибку:

Невозможно удалить индекс, потому что это не сбор статистики.

Также, если я попробую go в таблице «Статистика» в меню навигации, и попытаюсь сбросить с помощью контекстного меню, голос drop отключен.

Когда я пытаюсь найти его в таблице sys.stats, я получаю следующий результат:

Auto_Created: 0
User_Created: 0

Есть ли способ сбросить этот вид of statisti c?

EDIT

Благодаря ответу CR241 и комментарию Дэна Гузмана я смог найти какое-то решение этой проблемы. Я хотел ИЗМЕНИТЬ длину столбца nvarchar, но не смог этого сделать, потому что на это были некоторые ограничения. У меня была такая же проблема со многими таблицами базы данных. Это произошло потому, что с помощью помощника по настройке баз данных было создано множество индексов и статистики. Поэтому я создал сценарий для их удаления (в идеале было бы удалить и восстановить после изменения всех столбцов). Может быть, это будет еще кому полезно:

 GO
DECLARE selectIndexes CURSOR FOR
SELECT  
     QUOTENAME(SCHEMA_NAME(t.[schema_id]))
    + '.' + QUOTENAME(t.name) 
    + '.' + QUOTENAME(i.name) as FullIndexName
    FROM sys.indexes  i
    INNER JOIN sys.tables  t ON i.[object_id] = t.[object_id]
    INNER JOIN sys.stats  s ON s.object_id = i.object_id and s.name = i.name
    LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc ON i.Name = tc.CONSTRAINT_NAME 
            AND OBJECT_NAME(i.Object_ID) = tc.TABLE_NAME
    where QUOTENAME(i.name) like '__dta_%' and i.type_desc = 'NONCLUSTERED';



    DECLARE @fullIndexName nvarchar(max);

    DECLARE @sql NVARCHAR(max) = '';

    OPEN selectIndexes
FETCH NEXT FROM selectIndexes INTO @fullIndexName
WHILE (@@FETCH_STATUS = 0)
BEGIN
    set @sql = @sql+ 'DROP INDEX ' + @fullIndexName + CHAR(13) + CHAR(10);

    FETCH NEXT FROM selectIndexes INTO @fullIndexName
END

CLOSE selectIndexes
DEALLOCATE selectIndexes

print @sql;
--exec sp_executesql @sql;

1 Ответ

1 голос
/ 08 мая 2020

Сначала вы должны удалить индекс, затем автоматически удаляется его статистика, которая была создана с тем же именем, что и index. Так что я не думаю, что вам нужно сбрасывать статистику вручную.

SQL Сервер отслеживает созданную пользователем статистику через sys.stats , т.е. user_created. Вот почему при создании нового индекса, чтобы избежать этой ошибки, мы должны добавить следующий код IF EXISTS () перед фактическим кодом создания индекса.

Вот пример:

IF EXISTS ( SELECT *
FROM sys.indexes
WHERE name = N'IX_TestTable_1'
AND object_id = OBJECT_ID(N'[dbo].[TestTable]') )

DROP INDEX [dbo].[TestTable].[IX_TestTable_1]
GO

IF EXISTS ( SELECT *
FROM sys.stats
WHERE name = N'IX_TestTable_1'
AND object_id = OBJECT_ID(N'[dbo].[TestTable]')
AND user_created = 1 )

DROP STATISTICS [dbo].[TestTable].[IX_TestTable_1]
GO

CREATE NONCLUSTERED INDEX IX_TestTable_1 ON TestTable(Col1)

Должен имейте в виду, что можно удалить только статистику, созданную пользователем. Поэтому, если мы просто проверим наличие статистики по имени, он вернет ИСТИНА, но когда он попытается сбросить эту статистику, он выдаст следующую ошибку.

Cannot DROP the index ‘[dbo].[TestTable].[IX_TestTable_1]’ because it is not a statistics collection. 

Пожалуйста, проверьте это, чтобы узнать о sys.stats (Transact- SQL)

auto_created: указывает, была ли статистика автоматически создана SQL Сервером.

0 = Статистика не создавалась автоматически на SQL Сервер.

1 = Статистика была автоматически создана SQL Сервером.

...