索引 JSON 列 MySQL 8

Indexing JSON column in MySQL 8

所以我正在试验 json 列。 Mysql 8.0.17 应该使用多值 JSON 索引,如下所示:

CREATE INDEX data__nbr_idx ON a1( (CAST(data->'$.nbr' AS UNSIGNED ARRAY)) )

我有像这样 ["books"、"clothes"] 的 JSON 列类别。 我需要从 "books" 类别中获取所有产品。我可以使用 "json_contains" 或新的 "member of".

SELECT * FROM products WHERE JSON_CONTAINS(categories, '\"books\"')
SELECT * FROM products WHERE "books" MEMBER OF(categories)

并且有效。问题是 EXPLAIN 当然会显示查询正在进行完整 table 扫描,因此它很慢。

所以我需要一些索引。

我通过将 "unsigned" 类型替换为 "char(32) 来更改索引示例,因为我的类别是字符串而不是数字。我在 google 中找不到任何示例,所以我假设 char () 会好的,但不会。

这是我的索引查询:

CREATE INDEX categories_index ON products((CAST(categories AS CHAR(32) ARRAY)))

也试过

CREATE INDEX categories_index ON products((CAST(categories->'$' AS CHAR(32) ARRAY)))

但选择仍在进行完整 table 扫描。我做错了什么? 如何在不使用虚拟列的情况下正确索引 json 列?

对于多值 json 索引,json 路径必须匹配,因此索引

CREATE INDEX categories_index 
ON products((CAST(categories->'$' AS CHAR(32) ARRAY)))

您的查询还必须使用路径 ->'$'(或等效的 json_extract(...,'$')

SELECT * FROM products WHERE "books" MEMBER OF(categories->'$')

保持一致,它应该可以工作。

似乎没有显式路径的索引无法按预期工作,因此如果要使用整个文档,则必须指定 ->'$'。这可能是一个错误,但也可能是投射或自动投射到数组的预期行为。如果您指定路径,您将处于安全的一面。