В Вашем вопросе отсутствует солидная часть вводных данных. Какие ключи, где они "есть", сколько идёт выборка, почему именно INNER JOIN? и так далее.
Ключи (индексы) у Вас должны стоять на тех полях, которые участвуют в условии выборки, т.к. в фильтрации. В вашем конкретном случае, это:
ON t1.`firma` = t2.`firma` AND t1.`product` = t2.`product`
то есть, ключи (индексы) должны быть установлены на полях
firma и
product, при этом, если Вы хотите добиться максимальной скорости при подобной операции - помимо того, что на полях
firma и
product должны быть проставлены индексы типа
KEY - крайне желательно, что бы они были цифрами, т.к. с числами машины работают много быстрее.
Вообще, у всех объектов, которые Вы вот таким вот образом пытаетесь "склеить" друг с другом, должен быть какой-то уникальный идентификатор, ID, GUID или какой-то другой (на ваш выбор).
*Касательно именно чисел - зависит от ситуации конечно, в отдельных случаях это могут быть например GUID'ы, крайне желательно, что бы это были НЕ названия фирма, аля "ООО Рога и копыта" и НЕ названия продуктов, вроде "Батон нарезной #1".
Ну а если всё-таки Вам ну очень хочется использовать именно названия (заголовки) вместо уникальной идентификации каждого объекта, то имейте в виду, что в индекс попадают первые 255 символов. И, индекс по текстовым полям (CHAR/VARCHAR) - и сам по себе будет занимать больше, нежели его числовой аналог, и как следствие будет работать медленнее, нежели бы он был числом (идентификатором объекта).