Я заранее прошу прощения за то, что не имел всей доступной специфики, но машина строит индекс, вероятно, еще долго и почти полностью не отвечает.
У меня есть таблица на SQL Server 2005 с большим количеством столбцов, может быть, 20, но с огромным количеством строк (десятки, более вероятно, сотни миллионов). Чтобы упростить объем работы JPA, которую мне нужно было сделать, чтобы получить к ней доступ, я создал представление, содержащее интересующие меня биты. Представление было создано как:
SELECT bigtable.ID, bigtable.external_identification, mediumtable.hostname,
CONVERT(VARCHAR, bigtable.datefield, 121) AS datefield
FROM schema.bigtable JOIN schema.mediumtable ON bigtable.joinID = mediumtable.ID;
Когда я хочу выбрать из вида, я делаю:
SELECT * FROM vwTable WHERE external_identification = 'some string';
Это прекрасно работает в SQL Management Studio. Столбец external_identification имеет неуникальный некластеризованный индекс в bigtable. Это также отлично работало с нашей удаленно выполняющейся Java-программой в нашей тестовой среде. Теперь, когда мы находимся в одном или двух днях от производства, код немного изменился (хотя фундаментальный JPA NamedQuery все еще прост), но у нас новая установка SQLServer на новом оборудовании; тестовая версия была на 32-битной одноядерной машине, новое оборудование - 64-битной многоядерной.
Всякий раз, когда я пытаюсь запустить код, использующий это представление, на новом оборудовании, он либо зависает на неопределенный срок при первом вызове этого запроса, либо истекает время ожидания, если у меня указано время ожидания. После некоторых копаний что-то вроде:
SELECT status, command, wait_type, last_wait_type FROM sys.dm_exec_requests;
подтвердил, что запрос запущен, но показал его в состоянии:
suspended, SELECT, CXPACKET, CXPACKET
столько, сколько я хотел ждать. Всякий раз, когда я запускал один и тот же запрос из Management Studio, он выполнялся немедленно. Поэтому я провел небольшое исследование и выяснил, что это связано с ожиданием начала / завершения какой-то параллельной операции. Пытаясь обойти это, я установил для сервера MAXDOP значение 1 (отключенный параллелизм). После этого запрос все еще зависает, но sys.dm_exec_requests будет отображать:
suspended, SELECT, PAGEIOLATCH_SH, PAGEIOLATCH_SH
Это указывает на то, что это какая-то проблема HD / сканирования. Хотя, конечно, машина менее отзывчива, чем я ожидал бы для более нового оборудования, я не ожидал, что этот запрос (даже через представление) потребует большого сканирования, поскольку столбец, по которому я ищу, индексируется в базовой таблице, и он работает, если я запускаю его локально. Но только потому, что у меня нет идей и я нахожусь под прицелом, я добавляю индексы к представлению; сначала я должен добавить уникальный кластеризованный индекс (поверх идентификатора), прежде чем я смогу попытаться добавить неуникальный некластеризованный индекс поверх external_identification.
Я единственный, кто использует эту базу данных; когда я выбираю из sys.dm_exec_requests, единственными двумя результатами являются запрос, который я активно проверяю, и запрос select из sys.dm_exec_requests. Так что это не так, как будто он находится под законно тяжелой или даже при одновременной нагрузке.
Но я подозреваю, что цепляюсь за соломинку. Я не администратор баз данных, и каждый раз, когда мне приходится взаимодействовать с SQL Server, не обращаясь к нему, это сбивает с толку мою интуицию. У кого-нибудь есть идеи, почему запрос, выполненный удаленно, немедленно перешел бы в состояние ожидания, в то время как тот же самый запрос локально был бы выполнен немедленно?