一个很大的喜欢'匹配查询

时间:2017-05-18 15:09:32

标签: sql-server tsql

我有2张桌子, ' [Item] with field [name] nvarchar(255) ' [交易]字段[short_description] nvarchar(3999)

我需要这样做:

Select [Transaction].id,  [Item].id 
From [Transaction] inner join [Item]
on [Transaction].[short_description] like ('%' + [Item].[name] + '%')

以上作品仅限于少量商品,但未经过滤仅需20多分钟即可取消。

我在[name]上有一个NC索引,但由于它的长度,我无法索引[short_description]。

[Transaction] has 320,000 rows
[Items] has 42,000.

那是13,860,000,000种组合。

有更好的方法来执行此查询吗? 我确实捅了全文,但我并不是那么熟悉,答案并没有向我跳出来。

任何建议都赞赏!!

2 个答案:

答案 0 :(得分:3)

使用通配符(%或_)启动比较字符串将永远不会使用索引,并且通常会对性能造成灾难性后果。您的查询需要扫描索引而不是搜索它们,因此索引不会有帮助。

理想情况下,您应该有第三个表,它允许基于ID的Transaction和Item之间的多对多关系。设计是这里的问题。

答案 1 :(得分:0)

在进行了一些调查后,我使用了一些全文功能。

<强> sp_fulltext_keymappings 给我我的交易表ID,以及FT docID (我发现&#39; doc&#39; =文字字段)

<强> sys.dm_fts_index_keywords_by_document 给我FT documentId以及其中的各个关键字

有一次,其余的很简单。 虽然,我必须查看关键词&#39;多一点......似乎定义可以变化。

这只能起作用,因为我搜索的文字没有空格。 我相信你可以调整FTI配置以适应其他场景......但我无法承诺。 我需要更多地了解全文。

我目前的测试版&#39;代码如下。

CREATE TABLE #keyMap 
   (  
      docid INT PRIMARY KEY ,  
      [key] varchar(32) NOT NULL  
   );  
DECLARE @db_id int = db_id(N'<database name>');  
DECLARE @table_id int = OBJECT_ID(N'Transactions'); 

INSERT INTO #keyMap
 EXEC sp_fulltext_keymappings @table_id; 

select  km.[key] as transaction_id, i.[id] as item_id
from    
    sys.dm_fts_index_keywords_by_document ( @db_id, @table_id ) kbd  
    INNER JOIN 
    #keyMap km  ON km.[docid]=kbd.document_id
    inner join [items] i
    on kdb.[display_term] = i.name
   ;  

我的实际版本代码包括将数据插入到最终表中。 执行时间是30秒,这符合我现在的需要。