No i niestety tak juz bedzie, a to z jenego prostego powodu.
Zmiana granicy warunku zwieksza najwyrazniej w duzym stopniu ilosc znalezionych rekordow ktore wynikalyby z zapytania
Kod
SELECT count(*)
FROM on_air
WHERE idradio = 5 AND time >= '2011-05-22 02:20:06'
Wyobraz sobie ze jest to np. 200.000 rekordow.
Twoj limit 20 jest w tym przypadku tylko limitem wyswietlanych danych, a nie limitem dla zapytania.
A jasniej chodzi o to , ze przy warunku GROUP BY idsong MYSQL analizuje i grupuje w calym zbiorze znalezionych danych ( zalozmy 200.000 ), a nie w danych limitiwanych do 20.
Dodatkowo musi on posortowac caly zbior przez alias , ktory przybiera jakas wartosc dopiero po pogrupowaniu danych.
I dopiero po tych wszystkich happeningach

pokazuje pierwsze 20 wynikow.
W samym MYSQL sprawa jest dosc skomplikowana. W tego typu sytuacjach stosuje sie tzw "Faceted search", ale ma on niewiele wspolnego z MYSQL..
Z kolei w jezyku JAVA tego typu sytuacje mozna rozwiazac stosujac streamowanie wynikow i przniesienie dzieki temu czesci operacji obliczeniowych do warstwy logicznej. Pracujemy wtedy w trybie READ-ONLY , fetch-size ustawia sie na INTEGER_MIN_VAL i w ten sposob mozna bez narazania sie na OUT OF MEMORY przeprowadzic interesujaca Cie operacje w warswie logicznej ( oczywiscie tez w granicach zdrowego rozsadku ) .
Php niestety nie umie tego ....

Pomysl o innym rozwiazaniu , szczegolnie ze Twoja baza , jak wspominales wciaz rosnie.
Moze JAVA LUCENE ? ... ( Tylko nie pokus sie na ZEND LUCENE - odradzam )
Albo bazujac tylko na MYSQL jakis Trigger, ktory bedzie budowal Ci na biezaca jakas tabele wynikowa z ktorej pobierzesz dane bez takich perwersji

.
Pozdrawiam