我正在编写一个T-SQL查询,我正在开发电子商务网站,因为我使用了4个主要表:
我的管理部分有一个页面用于管理订单,现在我想按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]
ProductCategory表:
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]
答案 0 :(得分:1)
答案 1 :(得分:0)
首先尝试延长超时以查看它是否有效。而不是在你的执行计划中获取战利品。将包含较少元素的表移动到连接的左侧。
答案 2 :(得分:0)
这未经过测试,因此我不确定它是否仍然符合您的查询要求。
它将获取Order
的{{1}} OrderLineItem
Product
CategoryID
等于@CategoryID
或子类别@CategoryID
{1}}。
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)
关于性能,你只需要对其进行测试即可找到答案。
索引是一件好事,您应该确保在外键列上有索引。