2013-12-12 4 views
4

У меня есть следующая таблица:Почему SELECT COUNT (*) выполняет сканирование с кластерным индексом?

CREATE TABLE [dbo].[Addr](
    [Address] [char](34) NOT NULL, 
CONSTRAINT [PK_Addr] PRIMARY KEY CLUSTERED 
(
    [Address] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

И я пытаюсь выполнить запрос:

SELECT COUNT(*) 
FROM Addr 

Когда таблица содержит около 8 миллионов записей, он был немедленно выполняющийся. Но теперь таблица содержит 21 миллион записей, а запрос выполняется очень медленно. Managemet студия показывает следующий предполагаемый план:

Execution plan

Скриншот из вкладки Storage (Свойства таблицы):

enter image description here

Я использую MSSQL 2008 Express 10.50.1617.0. Почему этот простой запрос имеет такой сложный план?

+0

Возможно, я обнаружил свое собственное незнание SQL Server, но какой план вы выбрали для 'select count (Address) из Addr'? (Я буду * шокирован *, если они разные, просто любопытно.) –

+0

План совпадает с 'select count (Address) от Addr' – Zergatul

+1

Не может ли быть, что таблица теперь разделена? – bendataclear

ответ

4

Этот план не является сложным. Чтобы подсчитать количество записей, движок должен сканировать всю таблицу, но поскольку есть кластерный индекс, он использует его. Без кластеризованного индекса thre будет Table Scan вместо Clustered Index Scan. Если у вас был некластеризованный индекс в любом столбце, оптимизатор, скорее всего, будет выбирать этот индекс для подсчета записей, а операция будет быстрее.

+0

Но как объяснить, когда таблица содержала 8 миллионов записей, этот запрос выполнялся немедленно? – Zergatul

+2

@Zergatul: Возможно, вы перешли точку, где индекс вписывается в память. –

+3

@Zergatul - Вероятно, все страницы были в кеше. Он по-прежнему имел бы CI-сканирование, насчитывающее 8 миллионов строк. –

 Смежные вопросы

  • Нет связанных вопросов^_^