Как оптимизировать запрос T-SQL - PullRequest
5 голосов
/ 15 августа 2011

Я пишу T-SQL Query, я разрабатываю веб-сайт электронной коммерции, в котором я использую 4 основные таблицы:

  1. ProductCategory
  2. Product
  3. OrderLineItem
  4. Order

У меня есть одна страница в разделе администратора для управления заказами, Теперь я хочу отфильтровать по ProductCategory, то есть, какой Order содержитProduct (мой productId находится в OrderLineItem таблице), который связан с выбранным ProductCategory, я делаю это с помощью запроса ниже:

SELECT  
    O.OrderID,O.[OrderDate],O.[StatusID]                          
FROM [Order] O                              
INNER JOIN [Dyve_User] U ON U.[UserID] = O.[UserID]                               
INNER JOIN (SELECT OD.OrderID 
            FROM OrderLineItem OD
            LEFT OUTER JOIN [Product] P ON OD.ProductID = P.ProductID
            LEFT OUTER JOIN [ProductCategory] PC ON PC.CategoryID = P.CategoryID
            WHERE 
               (P.CategoryID = COALESCE(@CategoryID, P.CategoryID)                              
                OR P.CategoryID IN (SELECT CategoryID 
                                    FROM ProductCategory                              
                                    WHERE ParentID = COALESCE(@CategoryID, ParentID)
                                   )
               )                              
           ) AS T  ON O.OrderID = T.OrderID  

Мой этот запрос возвращает правильный результат, нокаждый раз запрос прерывается, может ли кто-нибудь сказать мне, как оптимизировать этот запрос, чтобы он не истекал?

Ниже приведена схема таблиц:

CREATE TABLE [dbo].[Order](
[OrderID] [int] IDENTITY(1,1) NOT NULL,
[OrderDate] [datetime] NULL,
[OrderTax] [money] NULL,
[OrderTotal] [money] NULL,
[ShippingCharge] [money] NULL,
[TrackingNumber] [varchar](50) NULL,
[TransactionStatusID] [int] NULL,
[UserID] [int] NULL,
[PromotionCode] [varchar](50) NULL
[ExpiryDate] [datetime] NULL,
[PaymentType] [tinyint] NULL
  CONSTRAINT [Order_PK] PRIMARY KEY CLUSTERED 
  (
[OrderID] ASC
 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,          ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

Таблица продукта:

CREATE TABLE [dbo].[Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[CategoryID] [int] NULL,
[ProductName] [nvarchar](600) NULL,
[ManufacturerID] [int] NULL,
[UnitPrice] [money] NULL,
[RetailPrice] [money] NULL,
[IsOnSale] [bit] NOT NULL,
[ExpiryDate] [datetime] NULL,
[IsElectrical] [bit] NULL,
[IsActive] [bit] NULL,
[ProductType] [int] NULL,
[AllowBackOrder] [bit] NULL
   CONSTRAINT [Product_PK] PRIMARY KEY CLUSTERED 
   (
[ProductID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,        ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
   ) ON [PRIMARY]

Таблица категорий продуктов:

CREATE TABLE [dbo].[ProductCategory](
[CategoryID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[Description] [nvarchar](max) NULL,
[ParentID] [int] NULL,
[IsActive] [bit] NULL
    CONSTRAINT [ProductCategory_PK] PRIMARY KEY CLUSTERED 
   (
[CategoryID] ASC
   )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,        ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

Таблица OrderLineItem:

CREATE TABLE [dbo].[OrderLineItem](
[OrderDetailID] [int] IDENTITY(1,1) NOT NULL,
[OrderID] [int] NOT NULL,
[ProductID] [int] NOT NULL
[TotalPrice] [money] NULL,
[Quantity] [int] NULL,
[Discount] [money] NULL,
[UnitPrice] [money] NULL,
[UserID] [int] NULL,
    CONSTRAINT [OrderLineItem_PK] PRIMARY KEY CLUSTERED 
      (
[OrderDetailID] ASC
   )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,        ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
   ) ON [PRIMARY]

Ответы [ 3 ]

1 голос
/ 15 августа 2011

Несколько вещей, с которых нужно начать:

  1. Определение индексов для объединения и столбцов где.
  2. Объединение таблиц меньших размеров в таблицы большего размера.

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

0 голосов
/ 15 августа 2011

Это не проверено, поэтому я не уверен, что он по-прежнему выполняет то, что вы хотели с вашим запросом.

Он выберет Order с OrderLineItem с Product с CategoryID, равным @CategoryID или дочерней категорией @CategoryID.

SELECT O.OrderID,
       O.[OrderDate],
       O.[StatusID]
FROM   [Order] AS O
WHERE  O.OrderID IN (SELECT OD.OrderID
                     FROM   OrderLineItem AS OD
                            INNER JOIN Product AS P
                              ON OD.ProductID = P.ProductID
                            INNER JOIN (SELECT PC.CategoryID
                                        FROM   ProductCategory
                                        WHERE  ParentID = @CategoryID
                                        UNION ALL
                                        SELECT @CategoryID) AS C
                              ON P.CategoryID = C.CategoryID)

Что касается производительности, вам просто нужно проверить это, чтобы узнать.

Индексы - это хорошо, и вы должны убедиться, что у вас есть индексы в столбцах внешнего ключа.

0 голосов
/ 15 августа 2011

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

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