cho*_*cki 2 mysql database indexing mysql-8.0
所以我正在试验 json 列。Mysql 8.0.17 应该使用多值 JSON 索引,如下所示:
CREATE INDEX data__nbr_idx ON a1( (CAST(data->'$.nbr' AS UNSIGNED ARRAY)) )
我有这样的 JSON 列类别 ["books", "clothes"]。我需要从“书籍”类别中获取所有产品。我可以使用“json_contains”或新的“成员”。
SELECT * FROM products WHERE JSON_CONTAINS(categories, '\"books\"')
SELECT * FROM products WHERE "books" MEMBER OF(categories)
Run Code Online (Sandbox Code Playgroud)
它有效。问题是当然 EXPLAIN 会显示有查询正在进行全表扫描,因此它很慢。
所以我需要一些索引。
我通过将“无符号”类型替换为“char(32)”来更改索引示例,因为我的类别是字符串而不是数字。我在谷歌中找不到任何示例,所以我认为 char() 会很好,但不是。
这是我的索引查询:
CREATE INDEX categories_index ON products((CAST(categories AS CHAR(32) ARRAY)))
Run Code Online (Sandbox Code Playgroud)
也试过
CREATE INDEX categories_index ON products((CAST(categories->'$' AS CHAR(32) ARRAY)))
Run Code Online (Sandbox Code Playgroud)
但选择仍在进行全表扫描。我做错了什么?如何在不使用虚拟列的情况下正确索引 json 列?
对于多值 json 索引,json 路径必须匹配,因此使用索引
CREATE INDEX categories_index
ON products((CAST(categories->'$' AS CHAR(32) ARRAY)))
Run Code Online (Sandbox Code Playgroud)
您的查询还必须使用路径->'$'(或等效的json_extract(...,'$'))
SELECT * FROM products WHERE "books" MEMBER OF(categories->'$')
Run Code Online (Sandbox Code Playgroud)
使其一致,它应该可以工作。
似乎没有显式路径的索引无法按预期工作,因此您必须指定->'$'是否要使用整个文档。这可能是一个错误,但也可能是将或自动转换为数组的预期行为。如果您指定路径,您将处于安全状态。