Dosłownie szalona odpowiedź, ale jeśli masz skonfigurowany system replikacji (w przypadku systemu z miliardem wierszy, mam nadzieję, że tak), możesz użyć przybliżonego oszacowania (jak MAX(pk)
), podzielić tę wartość przez liczbę niewolników masz, uruchom kilka zapytań równolegle.
W większości przypadków podzielilibyśmy zapytania na urządzenia podrzędne w oparciu o najlepszy klucz (lub chyba klucz podstawowy), w taki sposób (użyjemy 250000000 jako naszych wierszy / niewolników):
-- First slave
SELECT COUNT(pk) FROM t WHERE pk < 250000000
-- Ith slave where 2 <= I <= N - 1
SELECT COUNT(pk) FROM t WHERE pk >= I*250000000 and pk < (I+1)*250000000
-- Last slave
SELECT COUNT(pk) FROM t WHERE pk > (N-1)*250000000
Ale potrzebujesz tylko SQL. Co za popiersie. Ok, powiedzmy, że jesteś sadomasochistą. W systemie głównym (lub najbliższym niewolniku) najprawdopodobniej musisz utworzyć tabelę:
CREATE TABLE counter_table (minpk integer, maxpk integer, cnt integer, slaveid integer)
Zamiast więc wybierać tylko w twoich niewolnikach, musisz zrobić wstawkę, podobnie jak to:
INSERT INTO counter_table VALUES (I*25000000, (I+1)*250000000, (SELECT COUNT(pk) FROM ... ), @@SLAVE_ID)
Możesz napotkać problemy z niewolnikami piszącymi do stołu na master. Być może będziesz potrzebować jeszcze więcej sadis - mam na myśli, kreatywnych:
-- A table per slave!
INSERT INTO counter_table_slave_I VALUES (...)
W końcu powinieneś mieć urządzenie podrzędne, które istnieje jako ostatnie na ścieżce przechodzącej przez wykres replikacji, względem pierwszego urządzenia podrzędnego. Ten niewolnik powinien mieć teraz wszystkie inne wartości liczników i powinien mieć własne wartości. Ale zanim skończysz, prawdopodobnie są dodawane wiersze, więc będziesz musiał wstawić kolejny, kompensując zarejestrowany maksymalny pk w tabeli licznika i bieżący maksymalny pk.
W tym momencie musisz wykonać funkcję agregującą, aby dowiedzieć się, jakie są sumy wierszy, ale jest to łatwiejsze, ponieważ działałbyś na co najwyżej liczbie „niewolników, które masz i zmieniasz”.
Jeśli jesteś w sytuacji, w której masz oddzielne tabele w niewolnikach, możesz UNION
uzyskać wszystkie potrzebne wiersze.
SELECT SUM(cnt) FROM (
SELECT * FROM counter_table_slave_1
UNION
SELECT * FROM counter_table_slave_2
UNION
...
)
Albo wiesz, bądź nieco mniej szalony i migruj swoje dane do rozproszonego systemu przetwarzania, lub może skorzystaj z rozwiązania Data Warehousing (które zapewni Ci niesamowite awarie danych w przyszłości).
Uwaga: zależy to od tego, jak dobrze skonfigurowana jest Twoja replikacja. Ponieważ głównym wąskim gardłem będzie najprawdopodobniej trwała pamięć masowa, jeśli masz nieuporządkowaną pamięć masową lub źle posegregowane magazyny danych z dużym hałasem sąsiadów, prawdopodobnie spowoduje to wolniejsze działanie niż czekanie na pojedynczySELECT COUNT(*) ...
Ale jeśli masz dobrą replikację, to twój wzrost prędkości powinien być bezpośrednio związany z liczbą lub niewolnikami. W rzeczywistości, jeśli uruchomienie kwerendy liczącej zajmie 10 minut, a masz 8 niewolników, skrócisz czas do mniej niż kilku minut. Może za godzinę wyjaśnimy szczegóły tego rozwiązania.
Oczywiście tak naprawdę nigdy nie uzyskałbyś niezwykle dokładnej odpowiedzi, ponieważ to rozwiązanie rozproszone wprowadza trochę czasu, w którym wiersze mogą być usuwane i wstawiane, ale możesz spróbować uzyskać rozproszoną blokadę wierszy w tym samym wystąpieniu i uzyskać dokładną liczbę wierszy w tabeli dla określonego momentu w czasie.
W rzeczywistości wydaje się to niemożliwe, ponieważ w zasadzie utknąłeś w rozwiązaniu opartym tylko na SQL i nie sądzę, że masz mechanizm natychmiastowego uruchamiania podzielonego i zablokowanego zapytania na wielu urządzeniach podrzędnych. Być może, jeśli masz kontrolę nad plikiem dziennika replikacji ... co oznacza, że dosłownie rozpędzasz niewolników w tym celu, co bez wątpienia jest wolniejsze niż uruchamianie kwerendy liczenia na jednym komputerze.
Oto moje dwa grosze z 2013 roku.