A generated column with an index, for a JSON path

An expression in a WHERE clause cannot use an index, and a generated column moves the expression somewhere indexable.

ALTER TABLE products
  ADD COLUMN sku VARCHAR(32)
    GENERATED ALWAYS AS (meta->>'$.sku') STORED,
  ADD INDEX idx_sku (sku);

-- and the optimiser rewrites the original query to use it
SELECT * FROM products
WHERE JSON_UNQUOTE(JSON_EXTRACT(meta, '$.sku')) = 'ABC-1';
-- → uses idx_sku, with no application change

The automatic substitution is the good part and requires the expression to match exactly, which means the column definition has to use the same form the queries use. ->> is shorthand for extract-and-unquote and produces a real string rather than a JSON string with quotes around it, which is the difference between a working index and a silently empty one.