MySQL虚拟列和通配符

MySQL虚拟列和通配符,mysql,sql,query-optimization,sql-like,calculated-columns,Mysql,Sql,Query Optimization,Sql Like,Calculated Columns,我试着引用MySQL二级索引,奇怪的事情发生了 首先,我根据文档中的示例创建了一个表,并进行了一些小的修改 其次,我在文档中插入了每个示例的值 然后,我尝试用“like”和“wildcard”进行模糊搜索。这不起作用,因为索引不支持前缀%,但它可以得到结果 奇怪的是,我删除了前缀%,索引确实起了作用。然而,我没有得到任何结果。根据我对MySQL的拙劣理解,这应该是可行的 如果有人能帮助我,我将不胜感激。为了让您的查询正常工作,您需要一个生成的列,将名称提取为文本而不是JSON。也

我试着引用MySQL二级索引,奇怪的事情发生了

  • 首先,我根据文档中的示例创建了一个表,并进行了一些小的修改
  • 其次,我在文档中插入了每个示例的值
  • 然后,我尝试用“like”和“wildcard”进行模糊搜索。这不起作用,因为索引不支持前缀
    %
    ,但它可以得到结果
  • 奇怪的是,我删除了前缀
    %
    ,索引确实起了作用。然而,我没有得到任何结果。根据我对MySQL的拙劣理解,这应该是可行的

如果有人能帮助我,我将不胜感激。

为了让您的查询正常工作,您需要一个生成的列,将名称提取为文本而不是JSON。也就是说,使用
->
而不是
->

g VARCHAR(20) GENERATED ALWAYS AS (c ->> '$.name')
然后:索引可能对以下两种情况都有帮助:

where g like 'F%'
where g = 'F'
MySQL是否决定使用它是另一回事;基本上,数据库评估使用索引是否比完全扫描快。如果它认为条件将在大量行上匹配,它可能会选择完全扫描


请注意,我始终使用单引号表示字符串文字;尽管MySQL可以容忍其他情况,但这是SQL标准规定的。在其他一些数据库中,双引号表示标识符(这也符合标准)。

表中是否只有两行测试数据?您可能无法让MySQL使用索引,除非您存储了足够的行,这样做是值得的。此外,如果您搜索的模式匹配>20%的行,MySQL可能不会选择使用索引。优化器假设只扫描表比加载索引更便宜。顺便说一下,这两种可能性都不是使用虚拟列所特有的。当你在常规列上使用索引时,就会发生这种情况。@BillKarwin谢谢你的评论。然而,我的问题不是关于这一点。索引可以工作,但查询不能!它起作用了!但是为什么呢?在上面发布的示例中,我还为
c->'$.name'
创建了一个虚拟列。我分不清他们之间的区别。我会把你的回答标为最好的,如果你能进一步解释,我将不胜感激。谢谢你进一步的澄清。在本例中,我将查找文档并在谷歌上搜索
->
->
之间的区别。非常感谢你@Ray:
->
返回一个JSON值,因此它用双引号括起来,如
“Fred”
。如果您想要一个字符串值,您需要使用
->
将其解压缩,这样您就得到了
'Fred'
。在查询中尝试一下,然后自己找出答案。
select c->"$.name" as name from jemp where g like "%F%"
select c->"$.name" as name from jemp where g like "F%"
g VARCHAR(20) GENERATED ALWAYS AS (c ->> '$.name')
where g like 'F%'
where g = 'F'