【发布时间】:2014-10-17 22:37:34
【问题描述】:
我正在尝试创建一个拼字游戏机器人。因此,我将所有(270 万)波兰语单词都扔到了 SQL Server 数据库中,现在正致力于为正则表达式查询创建模式。我刚刚发现在WHERE 子句中添加一些条件可以使搜索效率更高。
例如,执行查询:
SELECT * FROM words WHERE dbo.[like](word, '^[def]{1,3}$') = 1;
持续约 43 秒,但添加了相当明显的长度条件:
SELECT *
FROM words
WHERE dbo.[like](word, '^[def]{1,3}$') = 1 AND LEN(word) <= 3;
将执行时间减少到 3 秒...您能告诉我原因,并建议一些有助于提高查询效率的技术吗?
附: like函数是用c#写的CLR:
public static bool Like(string text, string pattern)
{
Match match = Regex.Match(text, pattern);
return (match.Value != String.Empty);
}
【问题讨论】:
-
在您的表上尝试 FULL TEXT 索引:msdn.microsoft.com/en-ca/library/ms187317(v=sql.90).aspx
-
如果你有 270 万行,SQL Server 的查询优化器不可能知道哪些要检查,哪些不匹配你的正则表达式。但是,如果您添加
AND LEN(word) <= 3,则查询优化器可以排除 4 个或更多字符的所有单词,从而将对正则表达式检查器的调用应用于小得多的单词集 - 这就是为什么查询执行速度更快 -
一件简单的事情是将CLR函数更改为使用
Regex.IsMatch(text, pattern)。但是,通过将所有单词保存在内存中并使用您的客户语言可能会更好地解决这个问题。在 C# 中,您可以使用RegEx(pattern)构造函数来加快速度。您还可以查看诸如尝试之类的专业数据结构 -
@PieterGeerkens 我认为 CLR 函数不会使用全文索引。
-
@Laurence:当然——看起来 OP 并没有意识到这种能力,因此已经结束了使用 CLR 和 REGEX。我们的想法是尝试使用全文索引来减少所需的模式匹配。
标签: c# sql sql-server regex clr