1

我想优化一个表查找,因为执行计划显示一个相当大的并行化表扫描。该表格被称为Opportunity,我正在筛选的列是Name。具体来说,我想没有“补充”为Name的一部分,所有行:是否有可能写一个过滤索引的列值不是'X'?

WHERE ([Name] NOT LIKE '%Supplement%'); 

我换一种方式来优化这个环顾四周,整个过滤索引来到这正是我需要的,但他们不似乎不喜欢LIKE关键字。有没有一种替代方法来创建像这样的过滤索引?

该表有〜53k行,当直接查询服务器需要4秒钟获取数据,但是当我将它作为链接服务器查询时(这是我需要的)需要2分钟。为了改善这一次,我将查询移出了与链接服务器交谈的脚本,并在远程服务器上创建了一个视图。仍然需要永远。

这是我到目前为止已经试过,但SSMS说,这是无效的:提前

CREATE NONCLUSTERED INDEX [FX_NotSupplementOpportunities] 
    ON  [Opportunity]([Name]) 
    WHERE (([Name] NOT LIKE '%Supplement%') 
      AND ([Name] NOT LIKE '%Suplement%') 
      AND ([Name] NOT LIKE '%Supplament%') 
      AND ([Name] NOT LIKE '%Suppliment%')); 

感谢您的任何建议!

+0

不幸的是,你不能在SQL-Server中的筛选索引条件中使用LIKE。 – 2014-09-18 21:18:15

+0

有替代建议吗? – Gup3rSuR4c 2014-09-18 21:21:02

回答

3

您可以使用一个Indexes on Computed Columns 一个例子是:

CREATE TABLE [dbo].[MyTab](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Text] [varchar](max) NULL, 
    [OK] AS (case when NOT [text] like '%abc%' then (1) else (0) end) PERSISTED NOT NULL, 
CONSTRAINT [PK_MyTab] 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 
CREATE NONCLUSTERED INDEX [idx_OK] ON [dbo].[MyTab] 
(
    [OK] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
+0

感谢,接受但@ypercube的答案似乎是更好的答案,你可能会有机会做出决定。 – bummi 2014-09-19 19:50:54

2

不幸的是,你可以把什么过滤指数的条件很多局限性。

我无法找到任何具体的MSDN,但布伦特奥扎尔这篇博客文章:What You Can (and Can’t) Do With Filtered Indexes提到的几个局限性:

不能使用BETWEENNOT INCASE表情,OR

他们没有提到LIKE,但简单的测试(如你所做的)证实你不能。你甚至不能使用(NOT (a >= 7)),它可以改写为允许的(a < 7)

一个想法是使用一个持久列的情况下表达,然后在过滤索引使用持久的列 - 但是这就是过滤索引的另一个限制!

那么,你在做什么?唯一想到的是创建一个持久列,并将其用于简单的(未过滤的)索引。喜欢的东西:

ALTER TABLE dbo.Opportunity 
    ADD special_condition AS (CASE WHEN [Name] NOT LIKE '%Supplement%' 
            THEN 1 ELSE 0 END) 
     PERSISTED; 

然后添加一个索引,使用列:

CREATE NONCLUSTERED INDEX FX_NotSupplementOpportunities 
    ON dbo.Opportunity 
     (special_condition, [Name]) ; 

,并使用在查询的(WHERE special_condition = 1)

0

我选择了@ bummi的答案,因为它与我所尝试的最接近,但这不是我最终使用的。一点解释...

所以,很多时间试图找出如何使查询查找从一堆并行块的更快事实上,我出两个指数所追求的。我对此非常欣喜若狂,但最终我不得不放弃它。问题是远程数据库实际上是我们的Salesforce数据的备份。我不得不经历一些非常复杂的表和列更改前后同步,只是无法正常工作,并会每次同步擦除(每10分钟)。

虽然这样做最终打击了我导入数据,然后在我的结尾再次进一步格式化。我决定改为更新远程服务器上的视图,并尽可能在那里格式化数据,然后导入它。所以,我花了几个小时重新编写了SQL,并且我将〜25分钟脚本降低到了〜3分钟,这让我非常高兴和满意。最后,虽然远程服务器上的查询查询没有进行优化,但它们仍然非常快,主要是因为平均而言,我所接触的大多数表中不会超过〜50k行......

相关问题