MySQL 虚拟列和通配符
MySQL virtual column and wildcard
我正在尝试 MySQL 引用 MySQL Documentation 的二级索引,但奇怪的事情发生了。
- 首先,我根据文档
中的示例创建了一个 table 并稍作修改
create table jemp(
c JSON,
g VARCHAR(20) GENERATED ALWAYS AS (c->"$.name"),
INDEX i (g)
)
- 其次,我根据文档中的示例插入了值
INSERT INTO jemp (c) VALUES
('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'),
('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}');
- 然后,我尝试用“like”和“wildcard”进行模糊搜索。这不起作用,因为索引不支持前缀
%
,但它可以得到结果。
select c->"$.name" as name from jemp where g like "%F%"
- 奇怪的是,我删除了前缀
%
,索引确实起作用了。但是,我没有得到任何结果。根据我对 MySQL 的理解不足,这应该可行。
select c->"$.name" as name from jemp where g like "F%"
如果有人能帮助我,我将不胜感激。
为了使您的查询正常工作,您需要一个生成的列将名称 提取为文本 而不是 JSON。也就是说,使用 ->>
而不是 ->
:
g VARCHAR(20) GENERATED ALWAYS AS (c ->> '$.name')
那么:索引可能对以下两种情况都有帮助:
where g like 'F%'
where g = 'F'
MySQL是否决定使用它是另一回事;基本上,数据库会评估使用索引是否会比完全扫描更快。如果它认为条件会在大量行上匹配,它可能会选择全扫描。
请注意,我一直对字符串文字使用单引号;尽管 MySQL 容忍其他方式,但这就是 SQL 标准指定的内容。在其他一些数据库中,双引号代表标识符(这也是符合标准的)。
我正在尝试 MySQL 引用 MySQL Documentation 的二级索引,但奇怪的事情发生了。
- 首先,我根据文档 中的示例创建了一个 table 并稍作修改
create table jemp(
c JSON,
g VARCHAR(20) GENERATED ALWAYS AS (c->"$.name"),
INDEX i (g)
)
- 其次,我根据文档中的示例插入了值
INSERT INTO jemp (c) VALUES
('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'),
('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}');
- 然后,我尝试用“like”和“wildcard”进行模糊搜索。这不起作用,因为索引不支持前缀
%
,但它可以得到结果。
select c->"$.name" as name from jemp where g like "%F%"
- 奇怪的是,我删除了前缀
%
,索引确实起作用了。但是,我没有得到任何结果。根据我对 MySQL 的理解不足,这应该可行。
select c->"$.name" as name from jemp where g like "F%"
如果有人能帮助我,我将不胜感激。
为了使您的查询正常工作,您需要一个生成的列将名称 提取为文本 而不是 JSON。也就是说,使用 ->>
而不是 ->
:
g VARCHAR(20) GENERATED ALWAYS AS (c ->> '$.name')
那么:索引可能对以下两种情况都有帮助:
where g like 'F%'
where g = 'F'
MySQL是否决定使用它是另一回事;基本上,数据库会评估使用索引是否会比完全扫描更快。如果它认为条件会在大量行上匹配,它可能会选择全扫描。
请注意,我一直对字符串文字使用单引号;尽管 MySQL 容忍其他方式,但这就是 SQL 标准指定的内容。在其他一些数据库中,双引号代表标识符(这也是符合标准的)。