2011-08-15 24 views
5

Estoy escribiendo una consulta T-SQL, estoy desarrollando el sitio web de comercio electrónico, en el que estoy usando 4 mesas principales:Cómo optimizar la consulta T-SQL

  1. ProductCategory
  2. Producto
  3. OrderLineItem
  4. Solicitar

tengo una página en mi sección de administración para gestionar los pedidos, Ahora quiero filtrar por ProductCategory es decir, que Order contiene el Product (mi productId está en OrderLineItem tabla) que se relaciona con la seleccionada ProductCategory, estoy haciendo esto a través de abajo consulta:

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 

Mi esta consulta devuelve el resultado correcto, pero los tiempos de consulta a cabo cada vez, ¿alguien me puede decir cómo optimizar esta consulta para que no se agote el tiempo de espera?

siguiente es el esquema de tablas:

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] 

Tabla del producto:

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 Tabla:

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 Tabla:

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

¿Por qué haces LEFT JOIN aquí si solo quieres ver productos de una categoría específica? FROM OrderLineItem OD UNIÓN EXTERIOR IZQUIERDA [ProductCategory] PC EN PC.CategoryID = P.CategoryID WHERE (P.CategoryID = COALESCE (@CategoryID, P.CategoryID) – sll

Respuesta

0

Esto no ha sido probado, así que no estoy seguro de si todavía hace lo que pretendía con su consulta.

Se obtendrá los Order s que tiene un OrderLineItem con un Product con un CategoryID que es igual a @CategoryID o una categoría de niño a @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) 

En cuanto al rendimiento, solo tiene que probarlo para descubrirlo.

Los índices son una buena cosa y debe asegurarse de tener índices en las columnas de clave externa.

+0

Lo he intentado de esta manera pero obtengo el mismo error de tiempo de espera, por favor sugiéreme de otra manera – Vijjendra

+0

@Vijjendra - Podría ser útil si pudieras actualizar tu pregunta con las estructuras de tabla (DDL) incluyendo cualquier índice, cuántas filas contiene cada tabla y cuántas filas espera que se devuelvan con esto q uery. ¿Has intentado ejecutar la consulta en SSMS? –

+0

He actualizado mi pregunta con Table Schema. – Vijjendra

1

Un par de cosas para empezar con:

  1. Definir índices en las columnas de combinación y dónde.
  2. Únete desde las tablas más pequeñas a las más grandes.

Sugiero leer sobre el rendimiento y la manera de encontrar las causas - aquí es un buen artículo sobre el tema: part 1 y part 2.

+0

¿qué quiere decir? Únase desde las tablas más pequeñas a las más grandes? ? – Vijjendra

+0

@Vijjendra - Comience con las tablas que tienen menos datos y únase a tablas más grandes – Oded

0

Primero intente alargar el tiempo de espera para ver cómo funciona. Que tomar un botín en tu plan de ejecución. Mueva las tablas con menos elementos a la izquierda de la unión.

+0

Cómo mover tablas con menos elementos a la izquierda de la combinación? – Vijjendra

+0

Esto es lo que @Oded comentó "Comience con las tablas que tienen menos datos y únete a las tablas más grandes " –

Cuestiones relacionadas