【问题标题】:SQL Server Optimal Index on Substring?子字符串上的 SQL Server 最佳索引?
【发布时间】: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中选择,忽略第二个分号之前的所有内容,然后返回ActionHappenedFullMessage。比如我想

select ActionHappened, FullMessage 
from #Info 
where PartialMessage Like '%Activity D%'

但当然不是每列内的表扫描和软搜索。

感谢所有想法。

谢谢。

【问题讨论】:

  • 您应该将它们拆分为threadstartactivity 的单独列,而不是将其存储在无法索引且您需要分解以查询的连接字符串中.原子性甚至是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


【解决方案1】:

您能否像 Martin 建议的那样创建一个索引视图来分割字段?以下方法可能有效,但由于字段的大小,它可能无益。

  • 创建一个名为ReversePartialMessage
  • 的字段
  • 使用触发器通过 REVERSE(partialMessage) 填充此字段
  • PartialMessageReversePartialMessage 字段上添加索引
  • 创建 WHERE 子句

    PartialMessage Like 'Activity D%' 和 ReversePartialMessage Like 'D ytivitcA%'

但是,对于 PartialMessage 的大小,我不确定这些索引的工作是否会收获很多。如果可以缩短该字段,则这些索引可能是实用的。如果您确实创建了索引,请务必访问执行计划以查看它们是否实际使用。优化器可能决定表扫描比索引更有效。合并两个索引的输出的工作,特别是对于如此大的键值,可能不会产生任何显着的收益......

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2019-06-03
    • 2014-03-21
    相关资源
    最近更新 更多