SQL Server проблемы чтения столбцов с внешним ключом - PullRequest
2 голосов
/ 05 мая 2010

У меня странная ситуация, когда простые запросы, кажется, никогда не заканчиваются

например

SELECT top 100 ArticleID FROM Article WHERE  ProductGroupID=379114

немедленно возвращается

SELECT top 1000 ArticleID FROM Article WHERE  ProductGroupID=379114

никогда не возвращается

SELECT ArticleID FROM Article WHERE  ProductGroupID=379114

никогда не возвращается

SELECT top 1000 ArticleID FROM Article

немедленно возвращается

При возврате «я имею в виду» в анализаторе запросов появляется зеленая галочка с надписью «Запрос выполнен успешно».

Иногда я отображаю строки в сетке в qa, но запрос все еще продолжает ждать, пока мой клиент истечет - «иногда»:

SELECT     
   ProductGroupID AS Product23_1_, 
   ArticleID AS ArticleID1_, 
   ArticleID AS ArticleID18_0_, 
   Inventory_Name AS Inventory3_18_0_, 
   Inventory_UnitOfMeasure AS Inventory4_18_0_, 
   BusinessKey AS Business5_18_0_, 
   Name AS Name18_0_, 
   ServesPeople AS ServesPe7_18_0_, 
   InStock AS InStock18_0_, 
   Description AS Descript9_18_0_, 
   Description2 AS Descrip10_18_0_, 
   TechnicalData AS Technic11_18_0_, 
   IsDiscontinued AS IsDisco12_18_0_, 
   Release AS Release18_0_, 
   Classifications AS Classif14_18_0_, 
   DistributorName AS Distrib15_18_0_, 
   DistributorProductCode AS Distrib16_18_0_, 
   Options AS Options18_0_, 
   IsPromoted AS IsPromoted18_0_, 
   IsBulkyFreight AS IsBulky19_18_0_, 
   IsBackOrderOnly AS IsBackO20_18_0_, 
   Price AS Price18_0_, 
   Weight AS Weight18_0_, 
   ProductGroupID AS Product23_18_0_, 
   ConversationID AS Convers24_18_0_, 
   DistributorID AS Distrib25_18_0_, 
   type AS Type18_0_
FROM         
   Article AS articles0_
WHERE     
   (IsDiscontinued = '0') AND (ProductGroupID = 379121)

показывает это поведение.

Понятия не имею, что происходит. Вероятно, выбор сломан;)

Я получил внешний ключ в группах товаров

ALTER TABLE [dbo].[Article] WITH CHECK ADD CONSTRAINT [FK_ProductGroup_Articles] 
FOREIGN KEY([ProductGroupID]) 
REFERENCES [dbo].[ProductGroup] ([ProductGroupID]) 
GO 
ALTER TABLE [dbo].[Article] CHECK CONSTRAINT [FK_ProductGroup_Articles] 

есть около 6000 строк, и IsDiscontinued немного, но не null, но если пропустить это условие, это не изменит результат.

Кто-нибудь может сказать мне, как справиться с такой ситуацией? Больше информации, кто-нибудь?

Дополнительная информация: кажется, что этот внешний ключ не ограничивается этим, но все / некоторые ссылаются на эту сущность.

Ответы [ 4 ]

2 голосов
/ 05 мая 2010

Несколько вещей, которые я бы попробовал, чтобы попытаться помочь диагностировать проблему (может просто исключить):

Временно попробуйте запрос, который никогда не вернется, с табличной подсказкой NOLOCK или READPAST т.е.

SELECT top 1000 ArticleID FROM Article WITH (NOLOCK) WHERE ProductGroupID=379114

Это возвращает результаты или нет? Возможно, если где-то заблокирована строка или страница данных (каким-то процессом, который по какой-то причине имеет длительную блокировку), запрос задерживается им, что может показаться так.

Кроме того, выполните свой проблемный запрос (БЕЗ подсказки таблицы) в одном окне SSMS и запишите свой SPID (число в скобках в нижней строке рядом с учетной записью). В отдельном окне несколько раз выполните следующую команду и посмотрите, что она показывает:

SELECT status, wait_type
FROM sys.dm_exec_requests
WHERE session_id = <YourQuerySPID>

Здесь хорошая справка о том, что означают различные типы ожидания, и это может указывать на то, что запрос ожидает чего-то.

Обновление:
Смотрите этот ТАК вопрос о том, как найти заблокированные / блокирующие процессы. - Я не хочу отбирать голоса там, где есть ответы!

1 голос
/ 05 мая 2010

Пара вещей - другие уже указали в этих направлениях:

  • у вас есть индекс на вашем внешнем ключе ??

    CONSTRAINT [FK_ProductGroup_Articles] 
    FOREIGN KEY([ProductGroupID]) 
    REFERENCES [dbo].[ProductGroup] ([ProductGroupID]) 
    

    Создание внешнего ключа не автоматически создает индекс для этого столбца внешнего ключа - вопреки распространенному мнению.

    Если нет - это определенно поможет индексировать ProductGroupID - отдельно или в составном индексе.

  • Вы когда-нибудь создавали и обновляли свою статистику? Вы недавно вставили большое количество данных?

    Просто запустите эту команду для тех таблиц, которые задействованы в ваших запросах:

    UPDATE STATISTICS (table name)
    
  • небольшая проблема: если сравнить с колонкой BIT, я бы лично использовал

    (IsDiscontinued = 0) 
    

    Нет смысла помещать этот 0 в одинарные кавычки и, следовательно, превращать его в строку - SQL Server просто нужно преобразовать его обратно в BIT ....

1 голос
/ 05 мая 2010
  • У вас есть индекс для столбца ProductGroupID?Если да, фрагментированы ли ваши индексы?
  • Обновлена ​​ли ваша статистика?
  • Проверяли ли вы составленные планы запросов?Являются ли они одинаковыми?

Когда вы настраиваете производительность запроса, вы должны стремиться к тому, чтобы вы сравнивали его с одинаковыми, то есть каждый запрос извлекает набор результатов с диска, а не из буфераcache.

Вы можете очистить буферный кеш с помощью команды DBCC DROPCLEANBUFFERS , однако это НЕ часто используется для производственной базы данных.

Вы также захотите убедиться, чтостатистика актуальна для столбцов, которые являются частью предикатов предложения WHERE.Это гарантирует, что SQL Server определит наиболее оптимальный план запросов для использования на основе селективности ваших данных.

0 голосов
/ 05 мая 2010

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

CREATE NONCLUSTERED INDEX IX_Article_ProductGroupID ON dbo.Article 
    (
    ProductGroupID 
    ) INCLUDE (IsDiscontinued) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
 ON [PRIMARY]
GO

добавляет индекс на Article.ProductGroupID и охватывает Article.IsDiscontinued

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