Criar um Índice numa Propriedade JSON
Para tabelas grandes, consultar campos JSON pode ser lento. Para melhorar o desempenho, você pode criar um índice em um valor extraído de uma coluna JSON. No MariaDB, isso é alcançado primeiro adicionando uma coluna virtual baseada no campo JSON e, em seguida, criando um índice nessa coluna virtual.
Nesta etapa, você criará uma coluna virtual para a propriedade price e, em seguida, a indexará para acelerar consultas baseadas em preço.
Primeiro, adicione uma coluna virtual que extrai o preço dos dados JSON:
ALTER TABLE products ADD COLUMN price_virtual INT AS (CAST(JSON_UNQUOTE(JSON_EXTRACT(product_details, '$.price')) AS SIGNED)) STORED;
Este comando adiciona uma coluna virtual chamada price_virtual que calcula e armazena automaticamente o valor do preço a partir dos dados JSON.
Agora crie um índice nesta coluna virtual:
CREATE INDEX idx_product_price ON products (price_virtual);
Essa abordagem permite que o MariaDB procure eficientemente por linhas com base no preço numérico, utilizando a coluna virtual indexada.
Para confirmar que o índice foi criado, use o comando SHOW INDEXES.
SHOW INDEXES FROM products;
A saída listará todos os índices na tabela products, incluindo seu novo idx_product_price.
+----------+------------+-------------------+...
| Table | Non_unique | Key_name |...
+----------+------------+-------------------+...
| products | 0 | PRIMARY |...
| products | 1 | idx_product_price |...
+----------+------------+-------------------+...
A parte mais importante é verificar se o otimizador usa o índice. Você pode verificar isso com o comando EXPLAIN.
EXPLAIN SELECT product_name FROM products WHERE price_virtual > 1200;
Na saída do EXPLAIN, observe as colunas possible_keys e key. Você deverá ver idx_product_price listado, confirmando que o MariaDB está usando seu índice para executar a consulta de forma eficiente.
Você também pode consultar usando a expressão JSON original, e o otimizador do MariaDB ainda deverá ser capaz de usar o índice na coluna virtual:
EXPLAIN SELECT product_name FROM products WHERE CAST(JSON_UNQUOTE(JSON_EXTRACT(product_details, '$.price')) AS SIGNED) > 1200;
Você criou com sucesso uma coluna virtual e a indexou para otimizar consultas de propriedades JSON.
Você agora pode sair do shell do MySQL.
exit