我正在针对SQL Server 2005数据库构建一些自定义报告。该数据库属于我们运行的第三方管理应用程序。我要删除的数据不是网站的主要目的,因此除了时间戳列外,数据在很大程度上是未索引的。目前,只涉及一张桌子 - 一张约7亿行。因此,当我对其进行查询时,该查询只能返回50行时,它必须轮询全部7亿尔。

我希望加快这一速度,但不想为我添加到Where子句中的每一列索引 - 我不知道添加许多索引最终会提高速度(或者我是我)错误的?)。所以我很好奇如果我的最好做法是什么 不能 将任何新索引添加到表中!

存储过程似乎不是最合适的。索引视图可能是最好的主意?想法?

这是表格架:

DeviceGuid (PK, uniqueidentifier, not null)
DeviceID (int, not null)
WindowsEventID (PK, int, not null) (indexed)
EventLog (varchar(64), not null)
EventSource (varchar(64), not null)
EventID (int, not null)
Severity (int, not null)
Description (nvarchar(max), not null)
TimeOfEvent (PK, datetime, not null) (indexed)
OccurrenceNbr (int, not null)

这是一个示例查询:

SELECT COUNT(*) AS NumOcc, EventID, EventLog, EventSource, Severity, TimeOfEvent, Description
FROM WindowsEvent
WHERE DeviceID='34818'
    AND Severity=1
    AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM')
    AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM')
    AND EventID<>34113
    AND EventID<>34114
    AND EventID<>34112
    AND EventID<>57755
    AND EventSource<>'AutoImportSvc.exe'
    AND EventLog='Application'
GROUP BY EventID, EventLog, EventSource, Severity, Description
ORDER BY NumOcc DESC

也许查询很烂...它在4.5分钟内返回53行。

有帮助吗?

解决方案 3

这里的最终解决方案是针对索引字段运行查询,然后在运行查询的应用程序中过滤它们。两个字段最终包含了足够的信息,我可以对一个索引进行查询,并非常接近我想要的数据。我循环浏览并从结果列表中删除了所有非匹配实体。花了更少的时间!

其他提示

如果您的查询不使用任何索引,那将是真正的不好。您不需要每列上的索引,但是您需要在右列上。鉴于TimeOfevent已经被索引,因此它可能不是满足您的需求的绝佳选择。

右列将取决于数据的分布。最佳索引可能是提供最高选择性的索引(即,当您知道索引的键值时,它返回最少的行)。如果您知道提供最佳选择性的列,则可以在其上尝试索引。

为了帮助确定最佳索引,您可以在SSM中使用显示估计的执行计划。这将帮助您查看将使用哪些索引。添加索引后,您可以运行查询并通过执行计划评估结果。而且,当然,观察经过的时间也会有所帮助。

使用Double Row_number技巧尝试此方法:

SELECT  RN_Desc as NumOcc, *
FROM    (
        SELECT  row_number() Over(partition by EventId order by EventLog, EventSource, Severity, Description) as RN_Asc,
                row_number() Over(partition by EventId order by EventLog desc, EventSource desc, Severity desc, Description desc) as RN_Desc,
                *
        FROM    WindowsEvent 
        WHERE   DeviceID='34818' 
                AND Severity=1 
                AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM') 
                AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM') 
                AND EventID<>34113 
                AND EventID<>34114 
                AND EventID<>34112 
                AND EventID<>57755 
                AND EventSource<>'AutoImportSvc.exe' 
                AND EventLog='Application' 
        ) t
WHERE   RN_Asc = 1 
ORDER BY NumOcc DESC 

因此,引擎不需要仅通过表格进行任何聚合。如果它不起作用,请尝试使用Rownumber部分的订单和分区来播放正确的分组。

这很简单,但是我会尝试作为索引值作为第一个测试

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top