Добавление индекса JSON в MYSQL может привести к пустым результатам запросов
После того как я добавил индекс к полю json в базе данных, некоторые запросы Django перестали работать, поэтому я заглянул в базовый SQL и обнаружил нечто странное.
Вы можете воспроизвести проблему с помощью следующего 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: 8.0.29.
OS: Windows
Создано Django
SQL:
SELECT * FROM products WHERE status = 'active' AND JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Result:
id|status|info| --+------+----+
Использование простой строки
SQL:
SELECT * FROM products WHERE status = 'active' AND JSON_EXTRACT(info,'$."Group"') = 'G0001';
Result:
id|status|info | --+------+------------------+ 1|active|{"Group": "G0001"}|
Удаление избыточных условий запроса
SQL:
SELECT * FROM products WHERE JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Result:
id|status|info | --+------+------------------+ 1|active|{"Group": "G0001"}|
Как показано выше, я попробовал три способа запроса, но только первый из них дал пустые результаты. Я предполагаю, что это вызвано несоответствием типов сгенерированных столбцов.
Я обнаружил, что после удаления индекса первый работает нормально.
ALTER TABLE products DROP INDEX tag_group_idx;
SELECT * FROM products
WHERE status = 'active' AND
JSON_EXTRACT(info,'$."Group"') = JSON_EXTRACT('"G0001"', '$');
Может ли кто-нибудь подсказать мне истинную причину такого результата и как избежать влияния индекса на результаты запроса?
Спасибо!