MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

Poprawa wydajności zaplecza Część 2/3:Korzystanie z indeksów bazy danych

Indeksy baz danych są przedmiotem troski programistów. Mają potencjał, aby poprawić wydajność funkcji wyszukiwania i filtrowania, które używają zapytania SQL w zapleczu. W drugiej części tej serii artykułów pokażę wpływ indeksu bazy danych na przyspieszenie filtrów przy użyciu aplikacji internetowej Java opracowanej za pomocą Spring Boot i Vaadin.

Przeczytaj część 1 tej serii, jeśli chcesz dowiedzieć się, jak działa przykładowa aplikacja, której tutaj użyjemy. Kod znajdziesz na GitHub. Ponadto, jeśli wolisz, nagrałem wersję wideo tego artykułu:

Wymaganie

Mamy stronę internetową z siatką, która pokazuje listę książek z bazy danych MariaDB:

Chcemy dodać filtr, aby umożliwić użytkownikom tej strony sprawdzenie, które książki zostały opublikowane w określonym dniu.

Implementacja zapytania i usługi repozytorium

Musimy wprowadzić pewne zmiany w backendzie, aby obsługiwać filtrowanie danych według daty publikacji. W klasie repozytorium możemy dodać następującą metodę:

@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {

    Page<Book> findByPublishDate(LocalDate publishDate, Pageable pageable);

}

Wykorzystuje leniwe ładowanie, jak widzieliśmy w części 1 tej serii artykułów. Nie musimy implementować tej metody — Spring Data utworzy ją dla nas w czasie wykonywania.

Musimy również dodać nową metodę do klasy usługi (która jest klasą, której interfejs użytkownika używa do uruchamiania logiki biznesowej). Oto jak:

@Service
public class BookService {

    private final BookRepository repository;

    ...

    public Stream<Book> findAll(LocalDate publishDate, int page, int pageSize) {
        return repository.findByPublishDate(publishDate, PageRequest.of(page, pageSize)).stream();
    }

}

Dodawanie filtra do strony internetowej

Dzięki backendowi obsługującemu filtrowanie książek według daty publikacji, możemy dodać selektor dat do implementacji strony internetowej (lub widoku):

@Route("")
public class BooksView extends VerticalLayout {

    public BooksView(BookService service) {

        ...

        var filter = new DatePicker("Filter by publish date");
        filter.addValueChangeListener(event ->
                grid.setItems(query ->
                        service.findAll(filter.getValue(), query.getPage(), query.getPageSize())
                )
        );

        add(filter, grid);
        setSizeFull();
    }

    ...
}

Ten kod po prostu tworzy nowy DatePicker obiekt, który nasłuchuje zmian jego wartości (poprzez detektor zmiany wartości). Gdy wartość się zmieni, korzystamy z klasy usługi, aby książki zostały opublikowane w wybranym przez użytkownika dniu. Pasujące książki są następnie ustawiane jako elementy Grid .

Testowanie powolnego zapytania

Wdrożyliśmy filtr; jest jednak bardzo powolny, jeśli masz na przykład 200 tysięcy wierszy w tabeli. Spróbuj! Napisałem artykuł wyjaśniający, jak generować realistyczne dane demo dla aplikacji Java. Przy takiej liczbie wierszy aplikacji zajęło kilka sekund wyświetlenie danych na stronie internetowej na moim komputerze (MacBook Pro 2,3 GHz Quad-Core Intel Core i5). To całkowicie rujnuje wrażenia użytkownika.

Analizowanie zapytań za pomocą „Wyjaśnij zapytanie”

Jeśli włączyłeś rejestrowanie zapytań, możesz znaleźć zapytanie wygenerowane przez Hibernate w dzienniku serwera. Skopiuj go, zastąp znaki zapytania rzeczywistymi wartościami i uruchom go w kliencie bazy danych SQL. Właściwie mogę zaoszczędzić ci trochę czasu. Oto uproszczona wersja zapytania:

SELECT id, author, image_data, pages, publish_date, title
FROM book
WHERE publish_date = '2021-09-02';

MariaDB zawiera EXPLAIN oświadczenie, które daje nam przydatne informacje o tym, w jaki sposób silnik szacuje, że wykona zapytanie. Aby z niego skorzystać, po prostu dodaj EXPLAIN przed zapytaniem:

EXPLAIN SELECT id, author, image_data, pages, publish_date, title
FROM book
WHERE publish_date = '2021-09-02';

Oto wynik:

Dokumentacja zawiera wszystko, co musisz o niej wiedzieć, ale ważną częścią jest wartość w typu kolumna:WSZYSTKIE . Ta wartość mówi nam, że silnik szacuje, że będzie musiał pobrać lub odczytać wszystkie wiersze w tabeli. Niedobrze.

Tworzenie indeksu

Na szczęście możemy to łatwo naprawić, tworząc indeks w kolumnie, której używamy do filtrowania danych:publish_date . Oto jak:

CREATE INDEX book\_publish\_date_index ON book(publish_date);

Indeks bazy danych to struktura danych stworzona przez silnik, zwykle b-drzewo (b dla zrównoważonego ). Proces jest szybszy dzięki naturze b-drzewa — utrzymują uporządkowane dane, zmniejszając złożoność czasową z O(N) do O(log(N)), a nawet O(log(1)) w niektórych przypadkach.

Testowanie ulepszeń

Po zbudowaniu indeksu możemy ponownie uruchomić instrukcję EXPLAIN i zobaczyć, że kolumna typu pokazuje wartość ref zamiast WSZYSTKIE :

ref wartość oznacza, że ​​silnik użyje indeksu, gdy uruchomimy zapytanie. Ważne jest, aby to sprawdzić podczas dodawania indeksów do bardziej złożonych zapytań. Zawsze używaj EXPLAIN oświadczenie, aby dokładnie sprawdzić, czy po wprowadzeniu indeksu zyskujesz na wydajności.

Jeśli wypróbujesz aplikację internetową w przeglądarce i wybierzesz inną datę w selektorze dat (nie ma potrzeby restartowania serwera), zobaczysz ogromną różnicę! Na przykład dane są pobierane na moim komputerze w mniej niż sekundę, w przeciwieństwie do kilku sekund przed utworzeniem indeksu!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Analityka z MariaDB AX - tThe Open Source Columnar Datastore

  2. Jak działa UNCOMPRESS() w MariaDB

  3. Obsługa MariaDB 10.4 w zaktualizowanym dbForge Studio dla MySQL, v.8.1

  4. MariaDB UCASE() Objaśnienie

  5. Serwer MariaDB 10.0.33 jest już dostępny