3 индекса или один индекс с 2 столбцами в SQL Server 2008? - PullRequest
1 голос
/ 29 марта 2011

У меня SQL-запрос с предложением where, например:

Where ManufacturerID = @ManufacturerID
    AND ItemID IN (SELECT ItemID FROM @T)
            AND RelatedItemID IN (SELECT RelatedItemID FROM @T)

Что даст мне лучшую производительность или это правильный способ сделать это? 3 индекса - по одному на каждый столбец или один индекс, который включает все 3?

ЗДЕСЬ БОЛЬШЕ ПОЛНОГО ВИДА SP BEING RUN:

DECLARE @T TABLE (
    [CategoryID] [int] NOT NULL,
    [ManufacturerID] [int] NULL,
    [ItemID] [varchar](100) NOT NULL,
    [ItemName] [varchar](100) NULL,
    [PhotoName] [varchar](150) NULL,
    [ModifiedOn] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [IsDeleted] [bit] NOT NULL)

    ;WITH T As
(SELECT     CategoryID, ManufacturerID, ItemID, ItemName, PhotoName, ModifiedOn, ModifiedBy, IsDeleted
FROM         StagingCategoryItems
WHERE     (ManufacturerID = @ManufacturerID)
EXCEPT
SELECT     CategoryID, ManufacturerID, ItemID, ItemName, PhotoName, ModifiedOn, ModifiedBy, IsDeleted
FROM         CategoryProducts
WHERE     (ManufacturerID = @ManufacturerID)
)
INSERT INTO  @T
SELECT * 
FROM T


    DELETE FROM CategoryProducts WHERE ManufacturerID = @ManufacturerID
        AND ItemID IN (SELECT ItemID FROM @T)
        AND CategoryID IN(SELECT  CategoryID FROM @T)

    INSERT INTO [CategoryProducts]
           ([CategoryID]
           ,[ManufacturerID]
           ,[ItemID]
           ,[ItemName]
           ,[PhotoName]
           ,[CreatedOn]
           ,[CreatedBy]
           ,[ModifiedOn]
           ,[ModifiedBy]
           ,[DeletedOn]
           ,[DeletedBy]
           ,[IsDeleted])
      SELECT [CategoryID]
      ,[ManufacturerID]
      ,[ItemID]
      ,[ItemName]
      ,[PhotoName]
      ,[CreatedOn]
      ,[CreatedBy]
      ,[ModifiedOn]
      ,[ModifiedBy]
      ,[DeletedOn]
      ,[DeletedBy]
      ,[IsDeleted]
  FROM [StagingCategoryItems]
  WHERE ManufacturerID = @ManufacturerID
    AND ItemID IN (SELECT ItemID FROM @T)
            AND CategoryID IN(SELECT  CategoryID FROM @T)

Ответы [ 3 ]

1 голос
/ 29 марта 2011
ItemID IN (SELECT ItemID FROM @T)
AND RelatedItemID IN (SELECT RelatedItemID FROM @T)

Теперь это очень опасное состояние. Он выражает условие, что текущий ItemID находится в @T, а RelatedItemID также находится в @T, но обратите внимание, что они не обязательно должны находиться в одной строке в @T. Для примера, если @T содержит:

ItemID RelatedItemId
1      2
3      4

и в вашей таблице есть строка вроде:

ItemID  RelatedItemId
1       4

ГДЕ условие будет ИСТИНА. Вы уверены, что это разрешение, которое вы хотите?

Что касается вашего исходного вопроса об индексах: к сожалению, ответ на этот вопрос «это зависит». Количество комбинаций индексов может быть хорошим, и точно такие же индексы могут быть плохими, в зависимости от ваших фактических данных. Подходя к вопросу, подобному вашему, вы должны задать себе вопрос «какое условие является наиболее ограничительным и насколько оно ограничительным?».

Скажите, что ваш ManufacturerID = @ManufacturerID ограничит количество строк-кандидатов примерно до 10% (например, у вас есть 10 различных производителей), ItemID IN (SELECT ItemID FROM @T) ограничится постоянным размером в среднем 100 строк, а последнее условие выполнит тот же самый. Тогда даже одного индекса на ItemID будет достаточно. Особенно, если это кластеризованный индекс, но даже как индекс NC, вы говорите о среднем 100 ключевых запросов, что является небольшим изменением.

Но теперь давайте скажем, что, скажем, ваш ManufacturerID = @ManufacturerID ограничит количество строк-кандидатов примерно до 10%, ItemID IN (SELECT ItemID FROM @T) ограничит примерно 5% от общего числа строк, и последнее условие выполнит то же самое , но точное совпадение всех трех условий составляет только 0,0001% строк. Теперь нет одного столбца индекса поможет, вам нужен индекс, который включает в себя все три. В каком порядке? Отличный вопрос.

Я рекомендую вам ознакомиться с Общим руководством по проектированию индексов .

0 голосов
/ 29 марта 2011

Общее правило для любого SQL-сервера (PostgreSQL, Oracle, MySQL ....), а не только для вопроса о производительности Microsoft SQL Server, состоит в том, чтобы проверить его под своей рабочей нагрузкой и посмотреть, что дает план объяснения и соответствует ли производительность вашим требованиям. Протестируйте несколько вариантов и посмотрите, как они влияют на план объяснения и производительность (в большинстве случаев время до завершения). Я считаю, что вам не нужно даже много знать о базе данных, если вы можете доказать это с помощью действительно хорошего тестирования. Не то, что ноу-хау не имеет значения, но все ноу-хау в мире редко побеждают испытания в реальном мире.

0 голосов
/ 29 марта 2011

Один, так как два других являются табличными переменными.

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