了解Lucene的领先通配符性能(Understanding Lucene leading wild

2019-06-26 16:20发布

Lucene的默认不允许领先的搜索词通配符, 但可以启用有:

QueryParser#setAllowLeadingWildcard(true)

据我所知,使用通配符领先的防止Lucene的使用索引。 拥有国内领先的通配符搜索必须扫描整个索引。

如何表现出领先的通配符查询的性能? 当它确定以使用setAllowLeadingWildcard(true)

我已经建立了与模板10万个文档的测试指标:

{ name: random_3_word_phrase }

该指数是360M的磁盘上。

我的测试查询表现良好,我一直无法真正表现出的性能问题。 例如,查询name:*ing产生超过110万份文件,在不到1秒。 查询name:*ing*产生在同一时间超过150万份文件。

这是怎么回事吗? 为什么不是这样慢? 为10,000,000文件还不够吗? 执行文件需要包含的不仅仅是一个单一的领域吗?

Answer 1:

取决于你有多少内存,多少令牌指数是在内存中。

一个360MB的总指数可以很快搜索到任何旧的计算机上。 一个360GB指数将需要更长的时间...;)

举个例子,我启动了一个老2GB指数,并寻找“* E”。

在具有8GB的盒子,它返回500K打不到5秒。 我试着用的内存只有1GB的一箱相同的索引,并花了大约20秒。

为了进一步说明,这里的,基本上做了“** E *”类型的搜索1000万个的随机3个字的词组一些通用的C#代码。

static string substring = "E";

private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden

private static string RandomString(int size)
{
    StringBuilder builder = new StringBuilder();
    char ch;
    for (int i = 0; i < size; i++)
    {
        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
        builder.Append(ch);
    }

    return builder.ToString();
}

static void FindSubStringInPhrases()
{
    List<string> index = new List<string>();

    for (int i = 0; i < 10000000; i++)
    {
        index.Add(RandomString(5) + " " + RandomString(5) + " " + RandomString(5));
    }

    var matches = index.FindAll(SubstringPredicate);

}

static bool SubstringPredicate(string item)
{
    if (item.Contains(substring))
        return true;
    else
        return false;
}

毕竟千万阶段已加载到列表中,它仍然只需要大约一秒钟的“VAR匹配= index.FindAll(SubstringPredicate);” 返回超过400万的点击量。

问题的关键是,记忆是快。 一旦事情不能再加载到内存中,你必须开始交换到磁盘时,你会看到性能命中。



Answer 2:

如果我理解正确的话,该指数的一部分术语词典,这是所有索引项的排序列表。 当不带通配符或尾随通配符搜索,Lucene的可以利用的事实,许多方面有共同的前缀优势。 在另一方面,拥有国内领先的通配符搜索扫描整个学期字典。 这不是最优的,但是该术语词典趋于比索引的其他部分,诸如频率和位置数据是微小的,所以术语词典的一个全扫描通常不是大问题本身。



文章来源: Understanding Lucene leading wildcard performance