Низкая производительность SQL - PullRequest
7 голосов
/ 21 июня 2011

У меня есть следующий запрос:

 SELECT COUNT(Id) FROM Table

Таблица содержит 33 миллиона записей - она ​​содержит первичный ключ для идентификатора и никаких других индексов.

Запрос занимает 30 секунд.

Фактический план выполнения показывает, что он использует сканирование кластерного индекса.

Мы проанализировали таблицу и обнаружили, что она не фрагментирована с использованием первого запроса, показанного по этой ссылке: http://sqlserverpedia.com/wiki/Index_Maintenance.

Любые идеи относительно того, почему этот запрос такой медленный и как его исправить.

Определение таблицы:

 CREATE TABLE [dbo].[DbConversation](
[ConversationID] [int] IDENTITY(1,1) NOT NULL,
[ConversationGroupID] [int] NOT NULL,
[InsideIP] [uniqueidentifier] NOT NULL,
[OutsideIP] [uniqueidentifier] NOT NULL,
[ServerPort] [int] NOT NULL,
[BytesOutbound] [bigint] NOT NULL,
[BytesInbound] [bigint] NOT NULL,
[ServerOutside] [bit] NOT NULL,
[LastFlowTime] [datetime] NOT NULL,
[LastClientPort] [int] NOT NULL,
[Protocol] [tinyint] NOT NULL,
[TypeOfService] [tinyint] NOT NULL,
  CONSTRAINT [PK_Conversation_1] PRIMARY KEY CLUSTERED 
 (
[ConversationID] ASC
 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
 ) ON [PRIMARY]
 GO

Одна вещь, которую я заметил, - база данных настроена нарастут на 1 Мб.

Это живая система, поэтому мы ограничились тем, с чем мы можем играть - есть идеи?

ОБНОВЛЕНИЕ:

ОК - мы улучшили производительность вактуальный интересный запрос путем добавления новых некластеризованных индексов в соответствующие столбцы, так что это больше не является критической проблемой.

SELECT COUNT все еще медленный - пробовал его с подсказками NOLOCK - без разницы.

Мы все думаем, что это как-то связано с тДля Autogrowth установлено значение 1Mb, а не большее число, но он удивлен, что это имеет такой эффект.Может ли фрагментация MDF на диске быть возможной причиной?

Ответы [ 4 ]

5 голосов
/ 21 июня 2011

Это часто читаемая / вставленная / обновленная таблица? Есть ли действие обновления / вставки одновременно с вашим выбором?

Я предполагаю, что задержка вызвана конфликтом.

Я могу выполнить подсчет 189-метровых строк за 17 секунд на моем сервере разработки, но больше ничего не попало в эту таблицу.

Если вы не слишком беспокоитесь о разногласиях или абсолютной точности, вы можете сделать:

exec sp_spaceused 'MyTableName', который даст счет на основе метаданных.

Если вам нужен более точный подсчет, но вам не обязательно беспокоиться о том, что он отражает одновременную активность DELETE или INSERT, вы можете выполнить текущий запрос с подсказкой NOLOCK:

SELECT COUNT(id) FROM MyTable WITH (NOLOCK), который не получит блокировки на уровне строк для вашего запроса и должен работать быстрее.

2 голосов
/ 21 июня 2011

Мысли:

  • Используйте SELECT COUNT(*), что правильно для «сколько строк» ​​(согласно ANSI SQL). Даже если ID является PK и, следовательно, не обнуляемым, SQL Server будет считать ID. Не ряды.

  • Если вы можете жить с приблизительным количеством, используйте sys.dm_db_partition_stats. Смотрите мой ответ здесь: Самый быстрый способ подсчета точного количества строк в очень большой таблице?

  • Если вы можете жить с грязными чтениями, используйте WITH (NOLOCK)

1 голос
/ 21 июня 2011
use [DatabaseName]

select tbl.name, dd.rows from sysindexes dd
inner join sysobjects tbl on dd.id = tbl.id where dd.indid < 2 and tbl.xtype = 'U'

select sum(dd.rows)from sysindexes dd
inner join sysobjects tbl on dd.id = tbl.id where dd.indid < 2 and tbl.xtype = 'U' 

Используя эти запросы, вы можете получить счет всех таблиц в течение 0-5 секунд

используйте пункт where согласно вашему требованию .....

0 голосов
/ 21 июня 2011

Еще одна идея: если файлы растут частями 1 МБ, они могут быть фрагментированы в файловой системе.Вы не можете увидеть это с помощью SQL, вы видите это с помощью инструмента дефрагментации диска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...