我越来越意识到提高查询效率的重要性。至关重要的是,我有适当的索引等,以确保我的查询不会占用超过真正必要的IO。但这是一个只是丑陋的查询,我不知道如何使其有效。
我们假设我有一张表格,其中包含最基本形式的库存商品:
CREATE TABLE StockItems (
ItemID INT IDENTITY (1, 1) NOT NULL PRIMARY KEY,
SerialNo VARCHAR (50) NOT NULL
);
现在我需要编写一个存储过程,它将返回序列号与提供的部分序列号匹配的所有库存项目。以下查询将完全实现:
SELECT * FROM StockItems WHERE SerialNo LIKE '%' + @SearchStr + '%'
但是,当我看到这样一个问题时,我突然冷汗,紧紧抓住我的舒适毯子。 SerialNo
上没有索引,即使有,也没有任何意义,考虑到我正在寻找部分匹配。
有没有办法通过更高效的查询来实现此任务?
答案 0 :(得分:5)
在文本中搜索单词的问题与快速搜索序列号中的子串的问题完全不同。例如,倒置索引是文本分析中不可或缺的一部分,但看看它们如何适用于您的问题则不太明显。
您的问题是如何在实践中完成此操作。一种简单的方法是硬件。在数据库环境中,这将把包含序列号的表固定到内存中(如果表被大量使用并且不是太大,则默认情况下会发生这种情况)然后进行扫描。使用更多线程/处理器可以加快扫描速度,因此抛出硬件可以解决问题。
编写自定义代码(在亚马逊或谷歌就是这种情况)会使流程更快。
还有其他解决方案。如果字符串较大,则可以使用n-gram对字符串进行编码。 N-gram(在这种情况下)是字符序列,比如说3长,出现在字符串中(更多information)。
对于每个序列号,您可以分解所有n-gram序列并将它们存储在一个大的索引表中。然后在搜索字符串中查找所有n-gram。首先,只获得具有相同n-gram集的序列号。然后进行暴力搜索。
例如,如果你有序列号' 1234567890',那么它有以下三元组:123,234,456,567,678,789,890
如果您正在搜索%1919%
,那么任何匹配的字符串都需要有191和919.第一个字符串都没有,所以您不需要搜索它。