我有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种组合。
有更好的方法来执行此查询吗? 我确实捅了全文,但我并不是那么熟悉,答案并没有向我跳出来。
任何建议都赞赏!!
答案 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秒,这符合我现在的需要。