【问题标题】:SQL Performance, Execution plan showing mostly Index Scan instead of Index SeekSQL 性能,执行计划主要显示索引扫描而不是索引查找
【发布时间】:2023-03-12 02:29:01
【问题描述】:

我在查询下运行,该查询主要返回 25 条记录。但这需要将近20秒。而且表中的记录总数少于400,000。

SELECT * FROM Tickets 
LEFT OUTER JOIN HouseAccounts ON (Tickets.lHouseAccount_ID = HouseAccounts.lAccountID) 
LEFT OUTER JOIN Customers ON (Tickets.lCustomerID = Customers.lCustomerID) 
LEFT OUTER JOIN Vehicles ON (Tickets.lVehicleID = Vehicles.lVehicleID) 
WHERE (Tickets.sTicket_Number) NOT LIKE 'ADJ%' AND dbo.DateOnly(Tickets.dtCreated) between DATEADD(day, -60, dbo.DateOnly(GETDATE())) 
and dbo.DateOnly(GETDATE()) AND (Tickets.bDeleted = 0 or Tickets.bDeleted IS NULL)

下面是门票表结构

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Tickets](
 [Ticket_ID] [int] IDENTITY(1,1) NOT NULL,
 [lLocationID] [int] NULL,
 [dtCreated] [datetime] NULL,
 [dtUpdated] [datetime] NULL,
 [dtIn] [datetime] NULL,
 [dtOut] [datetime] NULL,
 [sTicket_Number] [nvarchar](10) NULL,
 [dblTotal] [float] NULL,
 [dblTaxes] [float] NULL,
 [dblTendered] [float] NULL,
 [dblChangeDue] [float] NULL,
 [bPaid] [smallint] NULL,
 [bCash] [smallint] NULL,
 [bCreditCard] [smallint] NULL,
 [bGiftCard] [smallint] NULL,
 [bHouseAccount] [smallint] NULL,
 [lHouseAccount_ID] [int] NULL,
 [sUserName] [nvarchar](25) NULL,
 [lUserID] [int] NULL,
 [lShiftNumber] [int] NULL,
 [imgSignature] [image] NULL,
 [sSignatureFileName] [nvarchar](25) NULL,
 [sPlate] [nvarchar](10) NULL,
 [sMake] [nvarchar](20) NULL,
 [sCarNumber] [nvarchar](25) NULL,
 [sDriverName] [nvarchar](64) NULL,
 [sZipcode] [nvarchar](5) NULL,
 [sAge] [nvarchar](10) NULL,
 [sGender] [nvarchar](10) NULL,
 [sFleetCard] [nvarchar](25) NULL,
 [sFleetCardExp] [nvarchar](8) NULL,
 [bCheck] [smallint] NULL,
 [lVIPAccountID] [int] NULL,
 [lPointsThisVisit] [float] NULL,
 [lGreeterID] [int] NULL,
 [lCustomerID] [int] NULL,
 [lVehicleID] [int] NULL,
 [lWorkOrderID] [int] NULL,
 [sWorkOrderNumber] [nvarchar](8) NULL,
 [sVehicleMake] [nvarchar](20) NULL,
 [sVehicleColor] [nvarchar](20) NULL,
 [sVehicleState] [nvarchar](2) NULL,
 [sVehiclePlate] [nvarchar](9) NULL,
 [sVehicleDamage] [nvarchar](100) NULL,
 [sCustomerName] [nvarchar](25) NULL,
 [dtReturnDate] [datetime] NULL,
 [lOdometer] [int] NULL,
 [sRoomNumber] [nvarchar](6) NULL,
 [sSpaceNumber] [nvarchar](50) NULL,
 [bExpressTicket] [smallint] NULL,
 [lRateStructureId] [int] NULL,
 [sRateStructure] [nvarchar](25) NULL,
 [mRate] [money] NULL,
 [mSurcharge] [money] NULL,
 [mValidation] [money] NULL,
 [mPrepaid] [money] NULL,
 [mRefund] [money] NULL,
 [mMisc] [money] NULL,
 [bVoided] [smallint] NULL,
 [bCheckedOut] [smallint] NULL,
 [bClosedOut] [smallint] NULL,
 [bRefunded] [smallint] NULL,
 [lParkerId] [int] NULL,
 [bUpdated] [smallint] NULL,
 [bIndoor] [smallint] NULL,
 [iTimesPrinted] [smallint] NULL,
 [bAudit] [bit] NULL,
 [bArchived] [bit] NULL,
 [lCounterId] [int] NULL,
 [bPaymentOther] [bit] NULL,
 [sPaymentDescription] [nvarchar](50) NULL,
 [bScanned] [bit] NULL,
 [bPrinted] [bit] NULL,
 [bReversed] [bit] NULL,
 [sCashierTerminal] [nvarchar](50) NULL,
 [sGreeterTerminal] [nvarchar](50) NULL,
 [bLocked] [bit] NULL,
 [bWash] [bit] NULL,
 [bDeleted] [bit] NULL,
 [sDeletedBy] [nvarchar](125) NULL,
 [dtClosed] [datetime] NULL,
 [lCloserId] [int] NULL,
 [lCloserId2] [int] NULL,
 [bBarcodeScanned] [bit] NULL,
 CONSTRAINT [aaaaaTickets_PK] PRIMARY KEY NONCLUSTERED 
(
 [Ticket_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 65) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Tickets] ADD  CONSTRAINT [DF__Tickets__dblTota__014935CB]  DEFAULT ((0)) FOR [dblTotal]
GO

ALTER TABLE [dbo].[Tickets] ADD  CONSTRAINT [DF__Tickets__bPaid__023D5A04]  DEFAULT ((0)) FOR [bPaid]
GO

ALTER TABLE [dbo].[Tickets] ADD  CONSTRAINT [DF__Tickets__bCash__03317E3D]  DEFAULT ((0)) FOR [bCash]
GO

ALTER TABLE [dbo].[Tickets] ADD  CONSTRAINT [DF__Tickets__bCredit__0425A276]  DEFAULT ((0)) FOR [bCreditCard]
GO

ALTER TABLE [dbo].[Tickets] ADD  CONSTRAINT [DF__Tickets__bGiftCa__0519C6AF]  DEFAULT ((0)) FOR [bGiftCard]
GO

还有,这里是索引和执行计划-

我已经尝试过更新统计信息和更新索引。然而,没有任何帮助。请提出建议,如何提高查询的性能。

Execution Plan.sqlplan

Execution Plan.xml

Indexes.xlsx

【问题讨论】:

  • 第 1 次 - 包含 DDL 以及执行计划的出色工作,这种情况很少发生。 2. 有什么方法可以将保存的执行计划作为一个文件包含进来,以便我们自己打开它?我相信这会更有益。
  • 另外,将索引复制/粘贴为文本会比屏幕截图更好,该屏幕截图不是很清晰(两者都适用)。如果这样更容易,索引 DDL 也可以。
  • Tickets 上的谓词及其组合都不能通过对现有索引的索引查找有效地实现,因此索引扫描也就不足为奇了。
  • @Igor - 上传了您需要的文件。让我知道你找到了什么。如果我可以对 DB(表/索引)而不是实际查询进行一些更改,我会更愿意。

标签: performance sql-server-2008 sql-execution-plan clustered-index non-clustered-index


【解决方案1】:

如果可能,您应该避免使用标量和多语句 UDF,因为它们很慢。而且您绝对应该在某些情况下避免使用它们,因为它们是不可预测的。将 dbo.DateOnly( 替换为 Convert(date, 应该会有所帮助。

我很好奇的事情 - 有未来的门票吗?如果有,你真的想跳过它们吗?很有可能,您可以将 between 替换为简单的 Tickets.dtCreated >= convert(date, DATEADD(day, -60, GETDATE()))

【讨论】:

  • 有什么建议我可以在数据库方面改进,因为查询无法访问。
  • Sql server 没有内联标量 UDF,所以对于优化器来说它是设计上的黑盒。在不更改查询的情况下,我没有办法改进它。
猜你喜欢
  • 1970-01-01
  • 2019-06-10
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多