0

У меня есть две таблицы, которые в большой степени опрошены несколькими пользователями. Для этих таблиц создаются средние запросы на 100+ (обновление/выбор)/вторых запросов.SQL Update Query with from clause Оптимизация

Родитель Детский

* GrantParent не участвует в присоединиться к так, я сказал только два стола

Мне нужно, чтобы изменить порядок всех детей для каждого родителя. Там может быть 3000-4000 родителей, и каждый родитель может иметь примерно столько же детей.

Типы столбцов: ParentID GUID ChildIndex INT FILEID Varchar IsDeleted бит

Таблицы группировались индекс на ПК и не кластерный индекс по столбцам используется в том, где.

UPDATE C SET C.ChildIndex = T.ReOrderedChildIndex FROM [Child] C INNER JOIN 
(
SELECT ROW_NUMBER() OVER (PARTITION BY dbo.Child.[ParentID] ORDER BY [ChildIndex] asc) AS ReOrderedChildIndex, 
     dbo.Child.ChildIndex, 
     dbo.Child.FileID, 
     dbo.Child.ParentID 

FROM dbo.Child WITH (NOLOCK) INNER JOIN 
        dbo.Parent WITH (NOLOCK) ON dbo.Child.ParentID = dbo.Parent.ParentID 
WHERE (dbo.Parent.GrandParentID = 1) AND (dbo.Child.IsDeleted = 0) 
) T 
ON C.FileID =T.FileID AND (C.ParentID=T.ParentID) AND (C.IsDeleted = 0) 

Это выглядит выше запрос займет больше времени и поставить запросы на выборку на ожидании, даже я использовал WITH (NOLOCK) во всех хранимых процедурах отбора данных.

Существует еще один запрос, который переупорядочивает родителей так же, как и для дочерних элементов в вышеуказанном запросе.

В действии Монитор блокировки показаны для выбора хранимых процедур.

Каков наилучший способ изменить порядок выполнения переупорядочения?

У меня возникли следующие проблемы и считаю, что они являются следствием этих запросов: 1- Случайно происходит взаимоблокировка. 2 Часто бывает время пула подключения.

* База данные доступны по окну приложения с использованием EntLib 4.0 с пулом подключений включены, бассейн максимального размером 200.

SQL Server 2008 R2

+0

Nolock не будет работать в запросе на изменение данных, вставить, обновить, удалить или слить. – jtimperley

+0

Вы разрешаете только один уровень отношений между родителем и ребенком? Родитель-> Ребенок или Родитель-> Ребенок1-> Ребенок2-> Ребенок3? – jtimperley

+0

Существует только один уровень. Ребенок может быть только ребенком, а родитель может быть только родителем, поэтому нет рекурсии или самостоятельного объединения. Все родители уникальны для одного бабушки и дедушки, и все дети уникальны для каждого родителя. Что касается Nolock в обновлении .. Я думал, что обновление имеет вложенный выбор, поэтому nolock следует рассматривать для выбора? – Munawar

ответ

0

Я бы рекомендовал реструктуризации данных к более гибкой схеме. Эта схема позволит использовать несколько уровней, чтобы вы могли объединить GrandParent, Parent и Child в одну таблицу логических отношений и одну таблицу логических данных. Вы также сможете использовать индексы для уменьшения блокировок и повышения производительности.

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

Схема:

CREATE TABLE dbo.EntityName 
(
    ID INT IDENTITY(1,1), 
    ParentID INT -- Todo: Add foreign key back to dbo.EntityName 
    -- Todo: Add primary key 
); 
GO 

CREATE TABLE dbo.Hierarchy 
(
    ParentID INT, -- Todo: Add foreign key back to dbo.EntityName 
    ChildID INT, -- Todo: Add foreign key back to dbo.EntityName 
    ChildLevel INT 
); 
GO 

Populate скрипт (немного грубо вокруг краев):

CREATE PROCEDURE [dbo].[uspBuildHierarchy] 
AS 
BEGIN 
    SET NOCOUNT ON; 

    CREATE TABLE #Hierarchy 
    (
     ParentID INT, 
     ChildID INT, 
     ChildLevel INT 
    ); 

    -- Add the root of your hierarchy 
    INSERT INTO #Hierarchy VALUES (1, 1, 0); 

    DECLARE @ChildLevel INT = 1, 
      @LastCount INT = 1; 

    WHILE (@LastCount > 0) 
    BEGIN 
     INSERT INTO #Hierarchy 
     SELECT 
      E.ParentID, 
      E.ID, 
      @ChildLevel + 1 
     FROM dbo.EntityName E 
     INNER JOIN #Hierarchy H ON H.ChildID = E.ParentID 
      AND H.ChildLevel = (@ChildLevel - 1) 
     LEFT JOIN #Hierarchy EH ON EH.ParentID = E.ParentID 
      AND EH.ChildID = E.ID 
     WHERE EH.ChildLevel IS NULL; 

     SET @LastCount = @@ROWCOUNT; 
     SET @ChildLevel = @ChildLevel + 1; 
    END 

    MERGE INTO dbo.Hierarchy OH 
    USING 
    (
     SELECT 
      ParentID, 
      ChildID, 
      ChildLevel 
     FROM #Hierarchy 
    ) NH 
    ON OH.ParentID = NH.ParentID 
     AND OH.ChildID = NH.ChildID 
    WHEN MATCHED AND OH.ChildLevel <> NH.ChildLevel THEN 
     UPDATE 
      SET ChildLevel = NH.ChildLevel 
    WHEN NOT MATCHED THEN 
     INSERT 
     VALUES 
     (
      NH.ParentID, 
      NH.ChildID, 
      NH.ChildLevel 
     ) 
    WHEN NOT MATCHED BY SOURCE 
     THEN DELETE; 
END 
GO 

запроса для всех детей хозяйствующего субъекта:

SELECT * 
FROM dbo.EntityName E 
INNER JOIN dbo.Hierarchy H ON H.ChildID = E.ID 
    AND H.ParentID = @EntityNameID; 
+0

На данный момент у меня есть 3 таблицы после нормализации. ГрандПарент, Родитель, Ребенок. У каждого объекта есть много связанных атрибутов, поэтому они хранятся отдельно в соответствующих таблицах. Как это вписывается в вашу предлагаемую схему? – Munawar

+0

Вы только рассказали нам, как они связаны в этот момент, я должен знать, что хранят таблицы. – jtimperley

+0

, чтобы уточнить, каждая таблица имеет еще 6 столбцов, которые не участвуют в этих изменениях/обновлениях, поэтому нормализованная форма была предпочтительнее, чем одна таблица для родительских и chillds. также есть только один уровень. один родитель не может быть дочерним для других, и у одного ребенка может быть только один родитель, так как мои знания, имеющие две таблицы, были лучше. Это плохо? – Munawar