COUNT(*) na tabeli z indeksowaną datą

0

Cześć,
mam tabelę, która ma kolumnę z datą. Dodatkowo na tej kolumnie z datą jest utworzony index.
Pytanie: w jaki sposób będzie obliczona wartość COUNT na takiej tabeli jeśli będę chciał ustawić warunek WHERE data > ... AND data < ...?
Czy baza będzie musiała zliczyć wszystkie rekordy, które spełniają warunek (daty) czy może zrobi to nieco sprytniej i znajdzie pierwszy oraz ostatni element z datą i obliczy różnicę?
Z góry dzięki za pomoc.

3

Nie mam pojęcia i nie wiem, czy ktokolwiek poza producentem silnika Twojej bazy (bo różne silniki mogą to realizować w różny sposób) udzieli odpowiedzi gwarantowanej.
Od siebie powiem tylko, że w takiej sytuacji silnik powinien (co nie znaczy, że na pewno to zrobi!!) skorzystać z indeksu i jeśli nie mówimy o tabeli z jakąś zawrotną liczbą (którą trudno nazwać) rekordów, to nie musisz się martwić o to, jak silnik to policzy, bo i tak nie będzie to trwać na tyle długo, byś miał ochotę to optymalizować.

No ale jeśli jestem w błędzie i dostępna jest dokumentacja do jakiejś bazy na tak niskim poziomie, to chętnie przygarnę link i poczytam.

2
Fac napisał(a):

Nie mam pojęcia i nie wiem, czy ktokolwiek poza producentem silnika Twojej bazy (bo różne silniki mogą to realizować w różny sposób) udzieli odpowiedzi gwarantowanej.

explain jest tym słówkiem SQL, które jest żródłem odpowiedzi ... może nie gwarantowanej na wieki, ale mówiące szczegółową prawdę tu i teraz (tzn za 3 mc może się zmienić, ze względu na zmiany statystyk)

https://www.google.com/search?client=firefox-b-d&q=sql+explain

1

może zrobi to nieco sprytniej i znajdzie pierwszy oraz ostatni element z datą i obliczy różnicę?
Szukał bym w kontekście Twojej bazy danych informacji na temat planu zapytania np,. sqlite https://www.sqlite.org/eqp.html

1
ZrobieDobrze napisał(a):

explain jest tym słówkiem SQL, które jest żródłem odpowiedzi ... może nie gwarantowanej na wieki, ale mówiące szczegółową prawdę tu i teraz (tzn za 3 mc może się zmienić, ze względu na zmiany statystyk)

No nie wiem. Taki plan wykonania powie mi, owszem, że silnik użyje indeksu celem wyszukania (SEEK) konkretnych wartości ograniczających przedział. Ale nie mówi mi (albo tego nie dostrzegam), czy jak już znajdzie te dwa rekordy graniczne, to czy "otwiera" wszystkie strony znajdujące się pomiędzy dwiema granicznymi i zlicza rekordy w nich zawarte, czy może ma jakąś pomocniczą tablicę, w której zawarte są liczby rekordów znajdujących się w poszczególnych stronach (to wydaje mi się sensowne, ale nigdy nie natrafiłem na artykuł, który by to wyjaśniał - inna sprawa, że chyba nigdy go nie szukałem).
Wydaje mi się, że @Kofcio pytał raczej niskopoziomowo, aniżeli o to, czy akurat w tym przypadku silnik użyje pełnego skanu, czy wyszukiwania.

Swoją drogą, w planie zapytania jest sporo "cyferek", których jeszcze nie nauczyłem się wykorzystywać (czego oczywiście żałuję), bo ciągle brakuje czasu na zanurzenie się w dokumentacji. Gdy mi tego bardzo potrzeba, to nie ma czasu (jak w tym dowcipie z majstrem biegającym z pustą taczką). Gdy czas już się znajdzie, to człowiek nie pamięta, że miał poczytać. A znacie może jakąś dobrą książkę, albo artykuł, od którego mógłbym zacząć? Preferuję MS SQL.

1

czy może zrobi to nieco sprytniej i znajdzie pierwszy oraz ostatni element z datą i obliczy różnicę?

Czy to będzie sprytniej? Jeżeli indeks dopuszcza duplikaty to obliczenie różnicy nie gwarantuje poprawności. Jeżeli nie dopuszcza powtórzeń, to też nie bardzo, bo możesz mieć luki w zadanym okresie.

1

Jak interesują nas drobne ciekawe detale to trzeba by poszukać studenta baz danych, który jest na bieżąco i choć troche go interesuja bazy danych,
albo jakiś podręcznik.

0

Zajrzyj w źródła bazy open source np. PostgreSQL to się dowiesz.

1

Jeżeli tabela jest partycjonowana, to pójdzie szybciej (bo będzie zliczać tylko wybrane partycje). Takie kombinowanie ze zliczaniem zakresów dat i wejść w indeksach pewnie wyjdzie drożej niż skan całej tabeli.

1

Przy sensownej implementacji indeksu, nie powinno. Np. przy różnego rodzaju b-drzewach wystarczy znaleźć początek i koniec zakresu i policzyć liście pomiędzy bez porównywania treści. A jeśli poświęcimy trochę pamięci (i czasu przy operacjach insert i delete) na licznik liści pod danym węzłem, to zrobimy to w czasie log n. Numer pozycji może być nawet liczony na bieżąco w czasie wyszukiwania, wtedy na koniec zwykłe odejmowanie wystarczy.

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