LIMIT - czy mimo to przelicza całą bazę?

0

Mam takie zadanie...
Jest tabela N w której jest parametr: DATA i LICZBA.
Codziennie do tej tabeli dodaje się kilkadziesiąt LICZB.
Za jakiś czas jest konieczność zliczania tego, mniej więcej w taki sposób:
Zlicz zera, zlicz liczby większe od zera.
Zrobiłem zapytanie tego typu:

SELECT n.data, 
IFNULL((SELECT COUNT(*) FROM N as n1 WHERE n1.data = n.data AND n1.liczba > 0),0) as suma_full,
IFNULL((SELECT COUNT(*) FROM N as n2 WHERE n2.data = n.data AND n2.liczba = 0),0) as suma_zer
FROM n 
GROUP BY n.data
ORDER BY n.data
LIMIT 30

Zapytanie z początku trwało krótko. Teraz wykonuje się bardzo długo. Zakres danych jest ten sam (30). Zmiana w czasie wykonania zapytania zapewne wynika z faktu, że liczy z całej tabeli, a nie tylko z ostatnich 30 dat. Dobrze myślę?
Nie wiem czy kombinować z datami, czy może po prostu jakoś lepiej zbudować to zapytanie. Jestem tylko ciekaw czy faktycznie tak ten LIMIT (nie) działa?

1

Dobrze myślisz. LIMIT jest aplikowany jako ostatnia funkcja na całym zestawie wyników. Musisz przepisać zapytanie na coś w rodzaju:

SELECT n.DATA, 
    IFNULL((SELECT COUNT(*) FROM N AS n1 WHERE n1.DATA = n.DATA AND n1.liczba > 0),0) AS suma_full,
    IFNULL((SELECT COUNT(*) FROM N AS n2 WHERE n2.DATA = n.DATA AND n2.liczba = 0),0) AS suma_zer
FROM n 
    WHERE 
        n.DATA IN (SELECT DISTINCT n.DATA FROM n ORDER BY n.DATA LIMIT 30)
GROUP BY n.DATA
ORDER BY n.DATA

Klauzula where "na dzień dobry" ograniczy ci liczbę rekordów na których będziesz operować. Do tego indeks na n.DATA i będzie dobrze.

0

Zapytanie ładne i zgrane, ale nie działa :(
MySQL w wersji 5.5.40 jaką mam nie obsługuje LIMIT w podzapytaniach. Debian pokazuje mi najnowszą do zainstalowania 5.5.43 ale nie widzę informacji, aby ta wersja to wspierała.
Chyba, że pozostanie mi zainstalowanie ręcznie.

0

Zapytanie napisane ad hoc bez testowania.

0

Nie no, tak sądziłem, spoko :)
Też się nie spodziewałem, że może nie działać w podzapytaniu.
Generalnie to myślałem już sztucznie w WHERE wrzucić listę dat wcześniej wygenerowaną, albo przez zapytanie, albo programem/skryptem i do query po prostu ją wrzucić.

0
SELECT n.DATA, 
    IFNULL((SELECT COUNT(*) FROM N AS n1 WHERE n1.DATA = n.DATA AND n1.liczba > 0),0) AS suma_full,
    IFNULL((SELECT COUNT(*) FROM N AS n2 WHERE n2.DATA = n.DATA AND n2.liczba = 0),0) AS suma_zer
FROM n 
    WHERE 
        n.DATA IN (SELECT * FROM (SELECT DISTINCT n.DATA FROM n ORDER BY n.DATA LIMIT 30) as x)
GROUP BY n.DATA
ORDER BY n.DATA

aż nie wierzę, że zadziałało :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1