2012-11-16 12 views
5

Mamy stół innodb z 12 000 000 rekordów.Zeskanuj tabelę mysql, dlaczego pobieranie zestawów wyników rząd po rzędzie jest o wiele szybsze niż pobieranie ich w pamięci w całości?

Używam dwóch sposobów na SELECT * z tej tabeli za pomocą JDBC.

Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 

W ten sposób kierowca może przesyłać wyniki po wierszach, a skanowanie zajmuje siedem sekund.

Statement stmt =conn.createStatement();

Resultsets są całkowicie pobrane i przechowywane w memory.And ten sposób odbywa 21S!

Po prostu czujesz się zagubiony, dlaczego pobieranie zestawu wyników wiersz po wierszu jest szybsze niż pobieranie zestawu wyników uzupełnionego do pamięci klienta? Sposób przesuwania wierszy po wierszu nie powinien zabierać więcej czasu na przesyłanie sieciowe?

+0

Ile pamięci ma serwer "klient"? przy rekordach 12M istnieje duża szansa, że ​​odczytanie wszystkiego w pamięci spowoduje wywoływanie stronicowania i odejście dysku od tego może być znaczące. – Basic

+0

jvm klienta ma pamięć 2G, a argumentami jvm są "-server -Xms2g -Xmx2g -Xss256K". Po dodaniu 4G dla jvm, odczyt wszystkich wyników do pamięci zajmuje tylko 11 sekund. Wydaje się, że klient potrzebuje więcej niż jvm 3G, mały rozmiar jvm w rzeczywistości powoduje stronicowanie i odkładanie dysku. – IvyTang

Odpowiedz

1

Wystarczy rozwinąć mój komentarz na OP

Najprawdopodobniej jest to problem pamięci - odczyt wyników 12m do pamięci może spowodować stronicowania, chyba że klient ma dużo pamięci RAM. Jak tylko zaczniesz wyrzucać dysk, wydajność znacznie spadnie. Warto zauważyć, że jeśli zaczniesz zwiększać pamięć RAM, JVM ma pewne dziwactwa w tym, jak adresuje> 32G (przełącza się na wskaźniki 64-bitowe), co oznacza, że ​​podczas przejścia poza tryb 32G faktycznie tracisz dostępną pamięć i możesz mieć inne problemy w zależności od o tym, jak napisano twój kod.

Aby spojrzeć na wszystko z perspektywy, używamy elastycznego wyszukiwania w chwili obecnej do zaindeksowania ~ 60 milionów dokumentów. Prawdą jest, że użycie pamięci będzie bardziej zaangażowane, ponieważ obsługuje indeksy, pamięci podręczne itp., Ale nie rozważalibyśmy udzielenia mu mniej niż 16 GB pamięci RAM, aby uzyskać wydajne odpowiedzi. Spotkałem ludzi używających> 100G za odłamek dla naprawdę dużych zestawów rekordów.

Powiązane problemy