Добавление индекса 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"', '$');
Может ли кто-нибудь подсказать мне истинную причину такого результата и как избежать влияния индекса на результаты запроса?
Спасибо!