Еха! Това е най-сложното "сливане на индекси", което съм виждал.
Обикновено (може би винаги ), можете да създадете „композитен“ индекс, който да замести index-merge-intersect, и да работи по-добре . Променете key2 от само (pinned) към (pinned, DeviceId) . Това може отървете се от „пресечната точка“ и я ускорете.
По принцип оптимизаторът използва сливане на индекси само в отчаяние. (Мисля, че това е отговорът на въпроса за заглавието.) Всякакви леки промени в заявката или включените стойности и оптимизаторът ще изпълни заявката без обединяване на индекси.
Подобрение на временната таблица __codes е да създадете постоянна таблица с голям диапазон от стойности, след което да използвате диапазон от стойности от тази таблица във вашия Proc. Ако използвате MariaDB, тогава използвайте динамично изградената "последователност" таблица. Например 'таблицата' seq_1_to_100 е ефективно таблица от една колона с числа 1..100. Няма нужда да го декларирате или попълвате.
Можете да се отървете от другото REPEAT цикъл чрез изчисление времето от Code .
Избягване на LOOPs ще бъде най-голямата полза от производителността.
Свършете всичко това, тогава може да имам други съвети.