c# – 在SQLite LIKE中转义通配符(%,_)而不牺牲索引使用?
我有几个SQLite查询的问题.实际上,我开始认为SQLite不是为具有10行的表设计的,实际上,SQLite是一场噩梦.
以下查询 SELECT * FROM [Table] WHERE [Name] LIKE 'Text%' 工作正常EXPLAIN显示使用索引,约70ms后返回结果. 现在我需要从.NET SQLite驱动程序运行此查询,所以我正在更改查询 SELECT * FROM [Table] WHERE [Name] LIKE @Pattern || '%' 索引不被使用.当我在任何SQLite工具中运行以下查询时,索引也不会被使用 SELECT * FROM [Table] WHERE [Name] LIKE 'Text' || '%' 所以我猜SQLite没有任何一种预处理逻辑实现. 好.我们尝试解决它,我仍然是绑定变量,并执行以下操作 SELECT * FROM [Table] WHERE [Name] LIKE @Pattern 但现在我将%通配符符号附加到我的模式字符串的末尾,就像这样 command.Parameters.Add(new SQLiteParameter("@Pattern",pattern + '%')); 它工作非常慢我不能说为什么,因为当我从SQLite工具运行这个查询它可以正常工作,但是当我从.NET代码绑定这个变量它工作很慢. 好.我还在试图解决这个问题.我正在摆脱模式参数绑定并动态构建此条件. pattern = pattern.Replace("'","''"); pattern = pattern.Replace("%","%"); where = string.Format("LIKE '{0}%' ESCAPE ''",pattern); 索引不再被使用.没有使用ESCAPE.我看到,当我跑 EXPLAIN QUERY PLAN SELECT * FROM [Table] WHERE [Name] LIKE 'Text%' ESCAPE '' 一旦我删除ESCAPE,它将再次开始使用索引,查询在60-70ms内完成. UPDATE 以下是结果. EXPLAIN QUERY PLAN SELECT * FROM [RegistryValues] WHERE [ValueName] LIKE 'windir%' ESCAPE '' SCAN TABLE RegistryValues(?3441573 rows) 而没有ESCAPE的 EXPLAIN QUERY PLAN SELECT * FROM [RegistryValues] WHERE [ValueName] LIKE 'windir%' SEARCH TABLE RegistryValues USING INDEX IdxRegistryValuesValueNameKeyIdKeyHiveFileId(ValueName>?AND ValueName<?)(?31250行) UPDATE 刚找到这个 http://www.sqlite.org/optoverview.html 4.0 LIKE优化 ESCAPE子句不能出现在LIKE运算符上 那么那么该怎么办呢? 我明白了吗?我不能使用LIKE操作符在SQLite中搜索包含通配符的字符串.通过通配符我的意思是_%^! 这是不可能的,因为我不能逃脱他们. 我对吗? 解决方法
当%在最后时,索引只能与LIKE子句一起使用,以便SQLite可以将其重写为两个简单的比较(如EXPLAIN输出所示).
因此,要获得相同的效果,请自己编写比较. ... WHERE Name LIKE 'Text%' 使用: ... WHERE Name BETWEEN 'Text' AND 'Textzzzzzzzzzzzzz' 或作为参数: ... WHERE Name BETWEEN @Pattern AND @Pattern || 'zzzzzzzzzz' (这个构造永远不需要转义:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |