Adding a JSON index to MYSQL may result in empty query results
After I added an index to the json field in the database, some of Django's queries stopped working, so I looked into the underlying SQL and found something strange.
You can reproduce the problem with the following SQL.
CREATE TABLE `products` (
`id` bigint NOT NULL AUTO_INCREMENT,
`status` varchar(32) DEFAULT NULL,
`info` json DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
ALTER TABLE products ADD INDEX tag_group_idx ((
CAST(info->>'$."Group"' as CHAR(32)) COLLATE utf8mb4_bin
)) USING BTREE;
INSERT INTO products (status, info) VALUES('active', '{"Group": "G0001"}');
MySQL version: 8.0.29.
OS: Windows
Generated by Django
SQL:
SELECT * FROM products WHERE status = 'active' AND JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Result:
id|status|info| --+------+----+
Using plain string
SQL:
SELECT * FROM products WHERE status = 'active' AND JSON_EXTRACT(info,'$."Group"') = 'G0001';
Result:
id|status|info | --+------+------------------+ 1|active|{"Group": "G0001"}|
Remove redundant query conditions
SQL:
SELECT * FROM products WHERE JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Result:
id|status|info | --+------+------------------+ 1|active|{"Group": "G0001"}|
As shown above, I tried three ways to query, but only the first one had empty results. I guess it was caused by the mismatch of the generated column types.
I found that after I deleted the index, the first worked fine.
ALTER TABLE products DROP INDEX tag_group_idx;
SELECT * FROM products
WHERE status = 'active' AND
JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Can anyone tell me the real reason for this result and how to avoid the index affecting the query results?
Thank you!