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行......

相關問題