PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Wskazówka HINT_PASS_DISTINCT_THROUGH zmniejsza liczbę jednostek zwracanych na stronę dla żądania PageRequest poniżej skonfigurowanego rozmiaru strony (PostgreSQL)

Problem, z którym eksperymentujesz, jest związany ze sposobem korzystania z HINT_PASS_DISTINCT_THROUGH wskazówka.

Ta wskazówka pozwala wskazać Hibernate, że DISTINCT słowo kluczowe nie powinno być używane w SELECT oświadczenie wydane w bazie danych.

Korzystasz z tego faktu, aby umożliwić sortowanie zapytań według pola, które nie jest zawarte w DISTINCT lista kolumn.

Ale nie tak należy używać tej wskazówki.

Ta wskazówka musi być używana tylko wtedy, gdy masz pewność, że nie będzie różnicy między zastosowaniem lub nie DISTINCT słowo kluczowe do SQL SELECT oświadczenie, ponieważ SELECT instrukcja już pobierze wszystkie odrębne wartości per se . Pomysł polega na poprawie wydajności zapytania, unikając niepotrzebnego DISTINCT oświadczenie.

Zwykle dzieje się tak, gdy użyjesz query.distinct metoda w zapytaniach kryterialnych i join fetching relacje z dziećmi. Ten wspaniały artykuł @VladMihalcea wyjaśnij szczegółowo, jak działa podpowiedź.

Z drugiej strony, gdy używasz stronicowania, ustawi OFFSET i LIMIT - lub coś podobnego, w zależności od bazowej bazy danych - w SQL SELECT oświadczenie wydane w stosunku do bazy danych, ograniczające maksymalną liczbę wyników zapytania.

Jak wspomniano, jeśli użyjesz HINT_PASS_DISTINCT_THROUGH wskazówka, SELECT instrukcja nie będzie zawierać DISTINCT słowa kluczowego, a ze względu na twoje sprzężenia może potencjalnie dać zduplikowane rekordy twojej głównej encji. Te rekordy będą przetwarzane przez Hibernate w celu rozróżnienia duplikatów, ponieważ używasz query.distinct , aw razie potrzeby usunie duplikaty. Myślę, że to jest powód, dla którego możesz otrzymać mniej rekordów niż żądano w swoim Pageable .

Jeśli usuniesz wskazówkę, jako DISTINCT słowo kluczowe jest przekazywane w instrukcji SQL, która jest wysyłana do bazy danych, o ile projektujesz tylko informacje o głównej encji, pobierze wszystkie rekordy wskazane przez LIMIT i dlatego zawsze da ci żądaną liczbę rekordów.

Możesz spróbować fetch join twoje jednostki podrzędne (zamiast tylko join z nimi). Wyeliminuje to problem braku możliwości użycia pola, według którego chcesz sortować w kolumnach DISTINCT słowa kluczowego, a ponadto będziesz mógł zastosować, teraz zgodnie z prawem, podpowiedź.

Ale jeśli to zrobisz, pojawi się kolejny problem:jeśli użyjesz łączenia pobierania i paginacji, aby zwrócić główne encje i ich kolekcje, Hibernate nie będzie już stosować paginacji na poziomie bazy danych - nie będzie zawierać OFFSET lub LIMIT słowa kluczowe w instrukcji SQL i spróbuje pogrupować wyniki w pamięci. To jest słynny Hibernate HHH000104 ostrzeżenie:

HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!

@VladMihalcea wyjaśnij to bardzo szczegółowo w ostatniej części tego artykuł.

Zaproponował również jedno możliwe rozwiązanie twojego problemu, Funkcje okien .

Używasz przypadku, zamiast używać Specification Chodzi o to, aby zaimplementować własne DAO. To DAO musi mieć tylko dostęp do EntityManager , co nie jest zbyt wiele, ponieważ możesz wstrzyknąć swój @PersistenceContext :

@PersistenceContext
protected EntityManager em;

Po uzyskaniu tego EntityManager , możesz tworzyć natywne zapytania i używać funkcji okna do budowania na podstawie dostarczonego Pageable informacje, właściwa instrukcja SQL, która zostanie wydana w bazie danych. Daje to o wiele więcej swobody w wyborze pól używanych do sortowania lub czegokolwiek, czego potrzebujesz.

Jak wskazuje ostatni cytowany artykuł, Funkcje okien to funkcja obsługiwana przez wszystkie główne bazy danych.

W przypadku PostgreSQL można je łatwo znaleźć w oficjalnej dokumentacji .

Na koniec jeszcze jedna opcja, zasugerowana przez @nickshoe i wyjaśniona szczegółowo w artykuł cytował, polega na przeprowadzeniu procesu sortowania i stronicowania w dwóch fazach:w pierwszej fazie należy utworzyć zapytanie, które będzie odwoływać się do twoich encji podrzędnych i w którym zastosujesz stronicowanie i sortowanie. To zapytanie pozwoli Ci zidentyfikować identyfikatory głównych encji, które zostaną użyte w drugiej fazie procesu, aby uzyskać same główne encje.

Możesz skorzystać z wyżej wspomnianego niestandardowego DAO, aby zrealizować ten proces.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przyspiesz Django i Postgres za pomocą prostego pola JSON

  2. Czy można wykryć naruszenie klucza obcego w postgresie?

  3. Uzyskaj liczbę wierszy liczyć po GROUP BY

  4. Uzyskaj token dostępu do połączenia z PostgreSQL w Azure Functions

  5. Uruchom plik wsadowy za pomocą polecenia psql bez hasła