【发布时间】:2011-09-17 20:56:31
【问题描述】:
运行 SQL Server 2008,我有一个表,其中包含来自应用程序的几百万行日志信息转储。我试图弄清楚如何编写最佳索引来获取相关信息。
桌子看起来像这样。只是一个示例,实际的消息数据很长。
CREATE TABLE #Info(
[infoID] [int] IDENTITY(1,1) NOT NULL,
[ActionHappened] [datetime] NOT NULL,
[PartialMessage] [nvarchar](1500) NULL,
[FullMessage] [nvarchar](max) NULL,
CONSTRAINT [pk_info] PRIMARY KEY CLUSTERED([infoID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
Insert Into #Info Values ( GETDATE() , 'Thread:05;D:Start;Msg:Activity A' , 'Thread:05;D:Start;Msg:Activity A abcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyv' )
Insert Into #Info Values ( dateadd( minute , 3 , GETDATE() ) , 'Thread:05;D:Start;Msg:Activity B' , 'Thread:05;D:Start;Msg:Activity B abcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyv' )
Insert Into #Info Values ( dateadd( minute , 6 , GETDATE() ) , 'Thread:05;D:Start;Msg:Activity C' , 'Thread:05;D:Start;Msg:Activity D abcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyv' )
Insert Into #Info Values ( dateadd( minute , 9 , GETDATE() ) , 'Thread:05;D:Start;Msg:Activity D' , 'Thread:05;D:Start;Msg:Activity E abcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyv' )
Insert Into #Info Values ( dateadd( minute , 15 , GETDATE() ) , 'Thread:05;D:Start;Msg:Activity E' , 'Thread:05;D:Start;Msg:Activity F abcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyvabcdegghijklmnopqrstuvwxyv' )
我需要从PartialMessage中选择,忽略第二个分号之前的所有内容,然后返回ActionHappened和FullMessage。比如我想
select ActionHappened, FullMessage
from #Info
where PartialMessage Like '%Activity D%'
但当然不是每列内的表扫描和软搜索。
感谢所有想法。
谢谢。
【问题讨论】:
-
您应该将它们拆分为
thread、start、activity的单独列,而不是将其存储在无法索引且您需要分解以查询的连接字符串中.原子性甚至是first normal form的要求 -
完全同意之前的回答(+1)。另一个选项可以是 XML。您可以将 PartialMessage 转换为 XML 字段,然后您可以创建一个XML index(另见Performance Optimizations for the XML Data Type in SQL Server 2005)。最后,您可以使用 xquery 查询 XML 值。
-
我希望我能够编辑表架构。但我没有。这就是我在这里的原因。 :)
-
@Snowy - 为了可索引,这些值需要在某个地方分开 - 如果您不能更改原始表的架构,可能是另一个表?子字符串的唯一索引机制是全文索引,但是您对解析器如何将字符串分解为单词并没有太多控制权,因此不确定这会有多大帮助。
标签: sql sql-server-2008 select indexing