具有多个项目的 WHERE 过滤器非常快,但只有一个,它非常慢

问题描述 投票:0回答:0

在 SQL Server 中,如果我将 WHERE 子句中的

STORE_ID_FILTER
部分替换为以下各种 4 种可能性中的每一种,则需要花费右侧所示的时间来完成。为什么当过滤器中只有一个 ID 时,查询时间会如此急剧地增加,从不到一秒增加到一分多钟?!即使我将多个 ID 行更改为与单个 ID 行有效相同(例如将 105 替换为 -1,这是一个不存在的 ID),执行时间仍然如下所示:

store.Id in (483,105)              -- 0.5 seconds
(store.Id = 483 OR store.Id = 105) -- 0.5 seconds
store.Id = 483                     -- 1.5 MINUTES!!
store.Id IN (483)                  -- 1.5 MINUTES!!
SELECT store.accountNumber,
       employee.lastName,
       employee.firstName,
       employee.employeeNumber,
       workOrder.completedDate,
       workOrder.invoiceNumber,
       workOrder.version,
       workOrderVehicle.vin,
       workOrderVehicle.model,
       workOrderVehicle.manuallyInputVIN,
       vehicleType.vehicleType,
       workOrderService.code,
       abs(COALESCE(wovDetailers.Multiplier, 1)) *
       iif(wovDetailers.VehicleTypeId = 1, workOrderService.CarPayroll, workOrderService.TruckPayroll)
           / COALESCE(PayrollDivisor.Divisor, 1)                             pieceworkTotal,
       abs(COALESCE(wovDetailers.Multiplier, 1)) *
       iif(wovDetailers.VehicleTypeId = 1, workOrderService.CarPayroll, workOrderService.TruckPayroll)
           / COALESCE(PayrollDivisor.Divisor, 1)
           / DetailerCount.Count                                             pieceworkEarned,
       COALESCE(serviceStoreMinutes.Minutes / DetailerCount.Count / 60.0, 0) hours,
       COALESCE(NULLIF(workOrderService.Price, 0), serviceStorePrice.StatementPrice, 0) /
       DetailerCount.Count                                                   revenueEarned
FROM auto_Store store
         JOIN auto_WorkOrder workOrder ON workOrder.StoreId = store.Id
         JOIN auto_WorkOrderVehicle workOrderVehicle ON workOrderVehicle.WorkOrderId = workOrder.Id
         JOIN auto_VehicleType vehicleType ON vehicleType.Id = workOrderVehicle.VehicleTypeId
         JOIN auto_WorkOrderService workOrderService ON workOrderService.WorkOrderId = workOrder.Id
         JOIN WorkOrderVehicleDetailers wovDetailers
              ON workOrderVehicle.Id = wovDetailers.Id
         JOIN auto_Employee employee ON employee.Id = wovDetailers.EmployeeId
         JOIN DetailerCount ON DetailerCount.WorkOrderVehicleId = workOrderVehicle.Id
         LEFT JOIN PayrollDivisor ON PayrollDivisor.Version = workOrder.Version
         LEFT JOIN auto_ServiceStoreMinutes serviceStoreMinutes
                   ON serviceStoreMinutes.ServiceStoreId = workOrderService.ServiceStoreId
                       AND
                      workOrder.CompletedDate BETWEEN serviceStoreMinutes.StartDate AND COALESCE(serviceStoreMinutes.EndDate, GETDATE())
                       AND serviceStoreMinutes.VehicleTypeId = IIF(workOrderVehicle.VehicleTypeId = 1, 1, 2)
         LEFT JOIN auto_ServiceStorePrice serviceStorePrice
                   ON serviceStorePrice.ServiceStoreId = workOrderService.ServiceStoreId AND
                      workOrder.CompletedDate BETWEEN serviceStorePrice.StartDate AND COALESCE(serviceStorePrice.EndDate, GETDATE())

WHERE
    STORE_ID_FILTER
    AND workOrder.CompletedDate BETWEEN '2023-02-20' AND '2023-02-27'
ORDER BY store.Name, employee.LastName, employee.FirstName, workOrder.InvoiceNumber;

Microsoft SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64)

sql sql-server where-clause query-optimization
© www.soinside.com 2019 - 2024. All rights reserved.