2010-02-01 7 views
17

Wykonuję kwerendę "wybierz sumę (foo) z paska" na bazie danych MySQL, która podsumowuje rekordy 7,3 mm i zajmuje około 22 sekund na przebieg. Czy istnieje sztuczka do przyspieszenia kwot w MySQL?Czy można przyspieszyć sumę() w MySQL?

+0

Jest to możliwe w inne bazy danych; dawny. [Oracle] (http://en.wikipedia.org/wiki/Materialized_view), [MS SQL] (http://technet.microsoft.com/library/Cc917715), –

Odpowiedz

24

Nie, nie można przyspieszyć samej funkcji. Problem polega na tym, że wybierasz 7,3 miliona rekordów. MySQL musi przeskanować całą tabelę, a 7,3 miliona to całkiem spora liczba. Jestem pod wrażeniem, że tak szybko się to kończy.

Strategia, którą można zastosować, to podzielić dane na mniejsze podzbiory (być może według daty? Miesiąc?) I utrzymać łączną sumę dla starych danych, które nie ulegną zmianie. Można okresowo aktualizować sumę, a ogólną wartość można obliczyć, dodając sumę i wszelkie nowe dane, które zostały dodane od tego czasu, co będzie znacznie mniejszą liczbą wierszy.

3

Nie, niezupełnie. Zawsze będzie trzeba wyliczyć wszystkie wiersze w tabeli.

Można utworzyć dodatkową tabelę i zaktualizować sumę tam na każdej wstawce, zaktualizować, usunąć?

0

Jeśli zapytanie jest naprawdę proste, nie ... ale jeśli używasz bardziej złożone kwerendy (i skrócona go tutaj) mogłeś (prawdopodobnie) - jak za pomocą lepiej łączy ...

9

Turn na QUERY CACHE w mysql. Buforowanie jest domyślnie wyłączone. Musisz ustawić plik mysql ini.

-- hint mysql server about caching 
SELECT SQL_CACHE sum(foo) FROM bar; 

Optymalizator MySQL może zwrócić pamięć podręczną, jeśli nie wprowadzono żadnych zmian w tabeli.

Czytaj więcej tutaj: http://www.mysqlperformanceblog.com/2006/07/27/mysql-query-cache/

+0

Czy wartość buforowana zostanie zaktualizowana, gdy wartość 'foo' jest aktualizowany? Czy MySQL ponownie podsumuje całą tabelę ponownie przy następnym uruchomieniu zapytania? –

+1

@ BlueRaja-DannyPflughoeft pamięć podręczna zostanie wyczyszczona i ponownie podsumuje całą tabelę. –

1

Prawdopodobnie można spróbować dodać indeks na polu bar.foo. Indeks będzie zawierał wszystkie wartości kolumny słupkowej, ale jest mniejszy, a więc szybszy do skanowania niż oryginalna tabela foo, szczególnie jeśli foo ma dużo innych kolumn.

+0

Naprawiono błąd w odnoszeniu się do kolumny. powinien być bar.foo, a nie foo.bar. dzięki @ harry-b – hongliang

8

Dwie rzeczy tutaj:

1) nie należy robić za sumę 7,3 mln rekordów na bieżąco - wprowadzają tabele pomostowe zaspokajaniu potrzeb biznesowych (dzień, miesiąc, rok, dział, itp) i wypełnić je na harmonogramu, ewentualnie ponowne wykorzystanie tych tabel zamiast oryginalnej tabeli „surowego” (jak wybrać zestawione wartości za każdy dzień, kiedy trzeba kilka dni przerwy, itd.)

2) sprawdzić ustawienia transakcji

http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read