Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance SQLServer2008R2:大约15000个事件日志行(如何查询所有不同错误的列表?)_Performance_Tsql_Sql Server 2008 R2_Query Performance - Fatal编程技术网

Performance SQLServer2008R2:大约15000个事件日志行(如何查询所有不同错误的列表?)

Performance SQLServer2008R2:大约15000个事件日志行(如何查询所有不同错误的列表?),performance,tsql,sql-server-2008-r2,query-performance,Performance,Tsql,Sql Server 2008 R2,Query Performance,我有一个非常大的数据库,它存储了很多事件日志,大约1500万行。 当我尝试这个查询时,完全不可能得到一些结果 你知道我该怎么做吗?也许是索引视图 (顺便说一句:问题只是性能问题。除此之外,如果条目少得多,那么查询就正常工作了。) 各表: CREATE TABLE [dbo].[EntryTypes] ( [pk_EntryType] [int] IDENTITY(1,1) NOT NULL, [EntryType] [nvarchar](50) NOT NULL, CO

我有一个非常大的数据库,它存储了很多事件日志,大约1500万行。 当我尝试这个查询时,完全不可能得到一些结果

你知道我该怎么做吗?也许是索引视图

(顺便说一句:问题只是性能问题。除此之外,如果条目少得多,那么查询就正常工作了。)

各表:

CREATE TABLE [dbo].[EntryTypes]
(
    [pk_EntryType] [int] IDENTITY(1,1) NOT NULL,
    [EntryType] [nvarchar](50) NOT NULL,

    CONSTRAINT [PK_EntryTypes] 
       PRIMARY KEY CLUSTERED ([pk_EntryType] ASC)
) ON [PRIMARY]

CREATE TABLE [dbo].[LogNames]
(
    [pk_LogName] [int] IDENTITY(1,1) NOT NULL,
    [LogName] [nvarchar](50) NOT NULL,

    CONSTRAINT [PK_LogNames] 
       PRIMARY KEY CLUSTERED ([pk_LogName] ASC)
) ON [PRIMARY]


CREATE TABLE [dbo].[Sources]
(
    [pk_Source] [int] IDENTITY(1,1) NOT NULL,
    [Source] [nvarchar](50) NOT NULL,

    CONSTRAINT [PK_Sources] 
       PRIMARY KEY CLUSTERED ([pk_Source] ASC)
) ON [PRIMARY]

CREATE TABLE [dbo].[Servers]
(
    [pk_Server] [int] NOT NULL,
    [Server] [nvarchar](50) NOT NULL,

    CONSTRAINT [PK_Servers] 
       PRIMARY KEY CLUSTERED ([pk_Server] ASC)
) ON [PRIMARY]

CREATE TABLE [dbo].[Main]
(
    [pk_Main] [int] IDENTITY(1,1) NOT NULL,
    [Time] [datetime] NOT NULL,
    [EventId] [int] NOT NULL,
    [Id] [bigint] NOT NULL,
    [Msg] [ntext] NOT NULL,
    [Indx] [int] NOT NULL,
    [fk_Server] [int] NOT NULL,
    [fk_Source] [int] NOT NULL,
    [fk_LogName] [int] NOT NULL,
    [fk_EntryType] [int] NOT NULL,

    CONSTRAINT [PK_Main] 
       PRIMARY KEY CLUSTERED ([pk_Main] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

CREATE TABLE [dbo].[Errors]
(
    [pk_Error] [int] IDENTITY(1,1) NOT NULL,
    [Time] [datetime] NOT NULL,
    [ErrorMsg] [varchar](50) NOT NULL,
    [ErrorMsgFull] [ntext] NOT NULL,
    [fk_Server] [int] NOT NULL,

    CONSTRAINT [PK_Errors] 
       PRIMARY KEY CLUSTERED ([pk_Error] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

ALTER TABLE [dbo].[Errors] WITH CHECK 
  ADD CONSTRAINT [FK_Errors_Servers] 
  FOREIGN KEY([fk_Server]) REFERENCES [dbo].[Servers] ([pk_Server])

ALTER TABLE [dbo].[Errors] CHECK CONSTRAINT [FK_Errors_Servers]


ALTER TABLE [dbo].[Main] WITH CHECK 
   ADD CONSTRAINT [FK_Main_EntryTypes] 
   FOREIGN KEY([fk_EntryType]) REFERENCES [dbo].[EntryTypes] ([pk_EntryType])

ALTER TABLE [dbo].[Main] CHECK CONSTRAINT [FK_Main_EntryTypes]

ALTER TABLE [dbo].[Main] WITH CHECK 
   ADD CONSTRAINT [FK_Main_LogNames] 
   FOREIGN KEY([fk_LogName]) REFERENCES [dbo].[LogNames] ([pk_LogName])

ALTER TABLE [dbo].[Main] CHECK CONSTRAINT [FK_Main_LogNames]


ALTER TABLE [dbo].[Main] WITH CHECK 
   ADD CONSTRAINT [FK_Main_Servers] 
   FOREIGN KEY([fk_Server]) REFERENCES [dbo].[Servers] ([pk_Server])

ALTER TABLE [dbo].[Main] CHECK CONSTRAINT [FK_Main_Servers]


ALTER TABLE [dbo].[Main] WITH CHECK 
   ADD CONSTRAINT [FK_Main_Sources] 
   FOREIGN KEY([fk_Source]) REFERENCES [dbo].[Sources] ([pk_Source])

ALTER TABLE [dbo].[Main] CHECK CONSTRAINT [FK_Main_Sources]

1500万排也没那么大。只需确保服务器中有良好的索引和足够的RAM即可。在这种情况下,在
Main.fk_EntryType
上添加索引可能会大大提高性能。将
fk_服务器
fk_日志名
fk_源
以相同的顺序包含在同一索引中(以匹配查询的GROUP BY和order BY子句),也可能有所帮助

如果这些额外的表实际上都只有一列,那么首先只需将该数据存储在主表中,您可能会做得更好。这将允许索引以正确的顺序覆盖查询数据,从而为数据库节省大量重新排序结果的工作。如果不可能,则可能需要一个


最后一个选项是将
Main.Msg
ntext列移动到它自己的表中。如果您的数据库服务器内存非常有限,这将允许数据库将
Main
表的其余部分保留在内存中,以便进行更快的检索,而无需添加额外的索引。

1500万行并不是那么大。只需确保服务器中有良好的索引和足够的RAM即可。在这种情况下,在
Main.fk_EntryType
上添加索引可能会大大提高性能。将
fk_服务器
fk_日志名
fk_源
以相同的顺序包含在同一索引中(以匹配查询的GROUP BY和order BY子句),也可能有所帮助

如果这些额外的表实际上都只有一列,那么首先只需将该数据存储在主表中,您可能会做得更好。这将允许索引以正确的顺序覆盖查询数据,从而为数据库节省大量重新排序结果的工作。如果不可能,则可能需要一个

最后一个选项是将
Main.Msg
ntext列移动到它自己的表中。如果您的数据库服务器内存非常有限,这将允许数据库将
主表的其余部分保留在内存中,以便更快地检索,而无需添加额外的索引;
如果dbo中有许多行。[EntryTypes],请确保在[EntryType]上有索引(如果“错误”行少于表内容的两%并且足够多)。将其作为一个过滤索引,以获得更高的性能

尝试在联接中使用的所有列上放置非聚集索引(如果有多个列索引,则始终使用包含最多nr唯一值的列)

尝试将查询中的所有列都放在索引中,以获得覆盖索引的效果。 尝试通过和使用DISTINCT删除您的组

此外,请检查您的查询计划,查看哪些操作花费的时间最多,以及建议使用哪些新索引…

首先; 如果dbo中有许多行。[EntryTypes],请确保在[EntryType]上有索引(如果“错误”行少于表内容的两%并且足够多)。将其作为一个过滤索引,以获得更高的性能

尝试在联接中使用的所有列上放置非聚集索引(如果有多个列索引,则始终使用包含最多nr唯一值的列)

尝试将查询中的所有列都放在索引中,以获得覆盖索引的效果。 尝试通过和使用DISTINCT删除您的组

另外,请检查您的查询计划,查看哪些操作花费的时间最多,以及建议使用哪些新索引…

试试这个
有5个连接,我打赌它在每一个连接上循环,并执行最后一个连接的位置
您也可以在不使用GROUPBY的情况下执行SELECTDISTINCT,但它可能是相同的查询计划

并在dbo.EntryTypes.EntryType上放置一个非聚集索引

如果这不能解决问题,那么在dbo.Main.Msg上添加一个非聚集索引
我不同意Joel的观点,将Main.Msg放在一个单独的表中会有帮助
也不认为将所有这些FK添加到dbo.EntryTypes.EntryType索引会有所帮助

SELECT  dbo.Main.Msg
      , dbo.EntryTypes.EntryType
      , dbo.EventIds.EventId
      , dbo.LogNames.LogName
      , dbo.Servers.Server
      , dbo.Sources.Source         
  FROM dbo.Main
  JOIN dbo.EntryTypes
    ON dbo.EntryTypes.pk_EntryType = dbo.Main.fk_EntryType 
   AND dbo.EntryTypes.EntryType = 'Error'
  JOIN dbo.EventIds 
    ON dbo.EventIds.pk_EventId     = dbo.Main.fk_EventId   
  JOIN dbo.LogNames 
    ON dbo.LogNames.pk_LogName     = dbo.Main.fk_LogName   
  JOIN dbo.Servers
    ON dbo.Servers.pk_Server       = dbo.Main.fk_Server    
  JOIN dbo.Sources 
    ON dbo.Sources.pk_Source       = dbo.Main.fk_Source    
 GROUP BY  
       dbo.Main.Msg
     , dbo.EntryTypes.EntryType
     , dbo.EventIds.EventId
     , dbo.LogNames.LogName
     , dbo.Servers.Server
     , dbo.Sources.Source
 ORDER BY ...
为什么在所有这些
[nvarchar](50)
上没有独特的约束

这很奇怪。使用这种设计,a可能会有重复的消息创建唯一的行,但您没有报告[pk_Main]。

试试这个
有5个连接,我打赌它在每一个连接上循环,并执行最后一个连接的位置
您也可以在不使用GROUPBY的情况下执行SELECTDISTINCT,但它可能是相同的查询计划

并在dbo.EntryTypes.EntryType上放置一个非聚集索引

如果这不能解决问题,那么在dbo.Main.Msg上添加一个非聚集索引
我不同意Joel的观点,将Main.Msg放在一个单独的表中会有帮助
也不认为将所有这些FK添加到dbo.EntryTypes.EntryType索引会有所帮助

SELECT  dbo.Main.Msg
      , dbo.EntryTypes.EntryType
      , dbo.EventIds.EventId
      , dbo.LogNames.LogName
      , dbo.Servers.Server
      , dbo.Sources.Source         
  FROM dbo.Main
  JOIN dbo.EntryTypes
    ON dbo.EntryTypes.pk_EntryType = dbo.Main.fk_EntryType 
   AND dbo.EntryTypes.EntryType = 'Error'
  JOIN dbo.EventIds 
    ON dbo.EventIds.pk_EventId     = dbo.Main.fk_EventId   
  JOIN dbo.LogNames 
    ON dbo.LogNames.pk_LogName     = dbo.Main.fk_LogName   
  JOIN dbo.Servers
    ON dbo.Servers.pk_Server       = dbo.Main.fk_Server    
  JOIN dbo.Sources 
    ON dbo.Sources.pk_Source       = dbo.Main.fk_Source    
 GROUP BY  
       dbo.Main.Msg
     , dbo.EntryTypes.EntryType
     , dbo.EventIds.EventId
     , dbo.LogNames.LogName
     , dbo.Servers.Server
     , dbo.Sources.Source
 ORDER BY ...
为什么在所有这些
[nvarchar](50)
上没有独特的约束


这很奇怪。使用这种设计,a可以使用重复的消息创建唯一的行,但您没有报告[pk_Main]。

为什么需要
分组依据
?否则我会得到双倍。有很多相同的事件。据我所知,你有一个大约15000000行的表。您正在对表执行一个到一组引用表的连接,然后根据表上的主id进行聚合。即使查询确实返回了结果,读取15000000行也可能需要一些时间。也许你应该问另一个问题,包括样本数据和期望的结果