Jet/ACE 是不是使用带有 LIKE BeginsWith 查询的索引?
Posted
技术标签:
【中文标题】Jet/ACE 是不是使用带有 LIKE BeginsWith 查询的索引?【英文标题】:Does Jet/ACE use indexes with a LIKE BeginsWith query?Jet/ACE 是否使用带有 LIKE BeginsWith 查询的索引? 【发布时间】:2011-07-14 21:01:51 【问题描述】:我记得在某处阅读以避免 Jet SQL 中的 LIKE 运算符,因为它不会利用列上的索引。所以很久以前我开始写这样的“开始”查询:
WHERE MyColumn BETWEEN "SomeText" AND "SomeTextZZZ"
只要 MyColumn 列上有索引,BETWEEN 就会利用该索引。我现在开始质疑我的方式。 BETWEEN 方法从未真正让我失望,但感觉很笨拙。
我可以理解为什么“包含”查询不能使用索引:
WHERE MyColumn LIKE "*SomeText*"
但似乎在“开始于”查询中使用索引:
WHERE MyColumn LIKE "SomeText*"
这是一个如此明显的优化,Jet/ACE 团队会实施它。
谁能提供文档或基准测试来以某种方式解决这个问题?
【问题讨论】:
我一直认为它使用索引。它似乎确实比“包含”或“结束于”标准要快,所以我一直认为这意味着它以某种方式使用索引。我在 Jet 3.5 Database Engine Programmer's Guide(曾为 Jet 发布的唯一文档)中找不到任何相关信息。 更新了我对 2003 年访问的答案。 【参考方案1】:感谢 @cularis 提出 JETSHOWPLAN 创意。我自己没有想到它,我觉得有点傻。以下是 Access 2007 中的结果:
之间: 01) 限制表Vendors的行 使用索引“全名” 用于表达式“Vendors.FullName between "S" And "SZZZ"” 喜欢(开头): 01) 限制表Vendors的行 使用索引“全名” 对于表达式“Vendors.FullName Like “S*”” 喜欢(包含): 01) 限制表Vendors的行 通过扫描 测试表达式 "Vendors.FullName Like "*S*"" LIKE(以结尾): 01) 限制表Vendors的行 通过扫描 测试表达式 "Vendors.FullName Like "*S""从我的 showplan.out 文件的摘录中可以看出,笨拙的 BETWEEN 和 LIKE(开头)都使用了索引。这与通过扫描表(即一次检查每一行)过滤的 LIKE(包含)和 LIKE(结束于)形成对比。
当我周一回到我的 Access 2002 副本时,我将在 ACE Jet 之前的引擎上重新运行测试(尽管我希望得到类似的结果,尤其是基于 @David 在他对我的评论中的经验)原始问题)。
【讨论】:
【参考方案2】:您可以使用SHOWPLAN.OUT
文件来分析查询的执行计划。我会在有能力的时候提交测试。
编辑:
您在 Access 2003 上的查询结果:
BETWEEN:
01) Restrict rows of table Vendors
using index 'FullName'
for expression "FullName Between "S" And "SZZZ""
LIKE (begins with):
01) Restrict rows of table Vendors
using index 'FullName'
for expression "FullName Like "S*""
LIKE (contains):
01) Restrict rows of table Vendors
by scanning
testing expression "FullName Like "*S*""
LIKE (ends with):
01) Restrict rows of table Vendors
by scanning
testing expression "FullName Like "*S""
所以在 ACE 之前完全一样。
【讨论】:
以上是关于Jet/ACE 是不是使用带有 LIKE BeginsWith 查询的索引?的主要内容,如果未能解决你的问题,请参考以下文章
连接到 Jet/ACE 数据库的 Ubuntu Shiny 服务器
Excel 的 NETWORKDAYS 函数与 Jet ADO 的等效项
带有 Like 语句的 MS-Access 上的 SQL 请求似乎永远无法正常工作