It is so hard to read a SELECT when I don't know which columns are in which tables.
select u.fk_id_ad_format
from spd_unit AS u
join spd_ad AS a ON u.fk_id_ad = a.id_ad
where a.fk_id_campaign in (1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145,
1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157,
1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167)
and u.duration_time > 0
group by u.fk_id_ad_format
Why do you have GROUP BY if you don't have any aggregate functions? Logically this is what you have:
select DISTINCT u.fk_id_ad_format
from spd_unit AS u
join spd_ad AS a ON u.fk_id_ad = a.id_ad
where a.fk_id_campaign in (1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145,
1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157,
1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167)
and u.duration_time > 0
I vote for these indexes:
spd_ad: INDEX(fk_id_campaign, id_ad)
spd_unit: INDEX(fk_id_ad, duration_time, fk_id_ad_format)
The optimizer is likely to want to start with spd_ad, since (1) the WHERE clause probably filters the most there, and (2) it is smaller.
If the optimizer would like to run the other direction (start with spd_unit), then
spd_unit: INDEX(duration_time, fk_id_ad, fk_id_ad_format)
spd_ad: INDEX(id_ad, fk_id_campaign)
and it might say "using Join buffer", which is sometimes a useful optimization.
You could switch to DISTINCT, add those 4 indexes (plus Peter's), and see what the EXPLAIN gives you.
You should DROP any index that is a 'prefix' of a new one. For example, DROP KEY `t_anuncio_t_pecas_fk` (`fk_id_ad`) when adding INDEX(fk_id_ad, duration_time, fk_id_ad_format).