【问题标题】:Extremely Slow Performing SELECT执行极慢的 SELECT
【发布时间】:2009-12-07 14:32:55
【问题描述】:

我有一个包含 7,526,511 条记录的表,其定义如下:

/****** Object:  Table [dbo].[LogSearches]    Script Date: 12/07/2009 09:23:14 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[LogSearches](
    [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [Acct_ID] [int] NULL,
    [RecordCount] [int] NOT NULL,
    [PageNumber] [int] NOT NULL,
    [Site_ID] [int] NOT NULL,
    [SearchAPI] [bit] NOT NULL,
    [FormSearch] [bit] NOT NULL,
    [IPAddress] [varchar](15) NOT NULL,
    [Domain] [nvarchar](150) NOT NULL,
    [ScriptName] [nvarchar](500) NOT NULL,
    [QueryString] [varchar](max) NULL,
    [Referer] [nvarchar](1024) NOT NULL,
    [SearchString] [nvarchar](max) NOT NULL,
    [UserAgent] [nvarchar](2048) NULL,
    [Processed] [datetime] NOT NULL,
    [Created] [datetime] NOT NULL,
    [IntegerIP] [int] NULL,
 CONSTRAINT [PK_LogSearches] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[LogSearches] ADD  CONSTRAINT [DF_LogSearches_Processed]  DEFAULT (getdate()) FOR [Processed]
GO

ALTER TABLE [dbo].[LogSearches] ADD  CONSTRAINT [DF_LogSearches_Created]  DEFAULT (getdate()) FOR [Created]
GO

执行计划如下所示:

StmtText                                                                                 StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                 DefinedValues                                                                                                                                                                                                                                                    EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList                                                                                                                                                                                                                                                       Warnings Type                                                             Parallel EstimateExecutions
---------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ -------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------- ------------- ------------- ----------- ---------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
SELECT TOP 1 * FROM LogSearches                                                          1           1           0           NULL                           NULL                           1                                                        NULL                                                                                                                                                                                                                                                             1             NULL          NULL          NULL        0.0032832        NULL                                                                                                                                                                                                                                                             NULL     SELECT                                                           0        NULL
  |--Top(TOP EXPRESSION:((1)))                                                           1           2           1           Top                            Top                            TOP EXPRESSION:((1))                                     NULL                                                                                                                                                                                                                                                             1             0             1E-07         11848       0.0032832        [LOALogs].[dbo].[LogSearches].[ID], [LOALogs].[dbo].[LogSearches].[Acct_ID], [LOALogs].[dbo].[LogSearches].[RecordCount], [LOALogs].[dbo].[LogSearches].[PageNumber], [LOALogs].[dbo].[LogSearches].[Site_ID], [LOALogs].[dbo].[LogSearches].[SearchAPI], [LOALo NULL     PLAN_ROW                                                         0        1
       |--Clustered Index Scan(OBJECT:([LOALogs].[dbo].[LogSearches].[PK_LogSearches]))  1           3           2           Clustered Index Scan           Clustered Index Scan           OBJECT:([LOALogs].[dbo].[LogSearches].[PK_LogSearches])  [LOALogs].[dbo].[LogSearches].[ID], [LOALogs].[dbo].[LogSearches].[Acct_ID], [LOALogs].[dbo].[LogSearches].[RecordCount], [LOALogs].[dbo].[LogSearches].[PageNumber], [LOALogs].[dbo].[LogSearches].[Site_ID], [LOALogs].[dbo].[LogSearches].[SearchAPI], [LOALo 1             2956.71       8.279319      11848       0.0032831        [LOALogs].[dbo].[LogSearches].[ID], [LOALogs].[dbo].[LogSearches].[Acct_ID], [LOALogs].[dbo].[LogSearches].[RecordCount], [LOALogs].[dbo].[LogSearches].[PageNumber], [LOALogs].[dbo].[LogSearches].[Site_ID], [LOALogs].[dbo].[LogSearches].[SearchAPI], [LOALo NULL     PLAN_ROW                                                         0        1

(3 row(s) affected)

当我运行查询时,它不会在任何合理的时间范围内完成。我已经让查询运行了 5 分钟以上,但它仍然没有返回我要求的单行。这种缓慢的 SELECT 性能会对数据库产生其他影响,例如难以删除我们不再需要的行。

你知道我的瓶颈可能在哪里吗? 98 gig 数据库及其日志在 SQL Server 2008 上运行在 4 磁盘 RAID 10 上,驱动器上有超过 100 gig 的可用空间。

【问题讨论】:

  • 您确定您选择的行没有被另一个进程锁定的行/页面/数据库阻塞吗?尝试在查询末尾添加 (NoLock) 看看是否有帮助
  • 使用(NOLOCK)时是否返回
  • 它确实返回了 NOLOCK。看起来我犯了一个菜鸟错误,因为我一直在处理这张桌子。该死的。长。我要花很长时间才能清除我们不再需要的行。
  • 如果您使用的是 SQL 2005 /8,那么当您的危机结束时,您可能希望查看日志文件的分区表;您可以对数据进行分区,以便通过少量维护将当前月份的日志数据放入一个表中,而其余的则在另一个表中。可以是一个非常有用的工具;如果您在企业中,您可以将内容设置为离线或只读,这样会更好。
  • 是的,我绝对有兴趣按日期对表格进行分区,我只需要弄清楚如何使用它。那里的文档似乎过于技术性,因为设置起来应该相当简单。

标签: sql-server performance


【解决方案1】:

您是否检查过您是否遇到了阻塞问题?

【讨论】:

  • 最近几天我一直在和这张桌子打架,但这次没有。看来这毕竟可能是问题所在。我在尝试从该表中删除记录时遇到了连续问题,并错误地假设它是相同的旧东西。
【解决方案2】:

创建另一个具有所需结构的表并在那里复制/“泵送”数据,然后删除旧表并重命名新表是否有用?您可能需要针对特定​​ id 范围“批量”执行此操作:

INSERT INTO LogSearches_new ... SELECT * FROM LogSearches WHERE ID BETWEEN 1 AND 999999

【讨论】:

  • 不幸的是,当我尝试它时,该解决方案引起的问题与原始删除一样多:-(。我认为我需要解决磁盘 I/O 问题以加快速度。一直运行 PerfMon 24 小时,让我们看看它要说什么。