![]() |
![]() ![]() |
![]() |
![]() ![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 897 Pomógł: 40 Dołączył: 16.12.2003 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Witam,
mam taki problem: chcę wrzucić do tabeli 16 milionów rekordów zawierających losowe unikalne liczby z wybranego zakresu. Tabela jest prosta:
I teraz... Stworzyłem funkcję, która na wejściu ma zakres (min, max) oraz ilość rekordów, a która generuje losowe liczby i zapisuje je do tabeli. Działa na zasadzie dopełnienia liczby rekordów do wymaganej ilości.
Funkcja jest meganieoptymalna, bo za każdym przejściem pętli sprawdza, ile jest już rekordów w tabeli i kontynuuje działanie, dopóki nie zostanie osiągnięta docelowa liczba rekordów. Czas wstawiania 20 000 rekordów z zakresu 1 000 000 000 - 9 999 999 999 (zależy mi na liczbach 10-cyfrowych) to 2,5 minuty. Wstawienie 16 milionów rekordów to szacunkowo 33 godziny. Druga funkcja działa na zasadzie wstawienia określonej liczby rekordów (nie dopełnienia):
Funkcja jest o niebo szybsza, 20 000 rekordów to ~1 sek. Wada: nie zawsze wstawi wymaganą liczbę rekordów, bo nie ma sprawdzania, ile jest rekordów w tabeli, a jest INSERT IGNORE, żeby uniknąć duplikatów. To co chciałbym osiągnąć, to optymalizacja pierwszej funkcji - tak, żeby dopełniła mi tabelę do wymaganej liczby rekordów. Będę wdzięczny za wskazówki. -------------------- how many SEO experts does it take to change a light bulb,lightbulb,light,bulb,lamp,lighting,switch,sex,xxx
5-Reasons-why-you-should-NEVER-fix-a-computer-for-free |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. Skorzystaj z prepared statements do dodawania rekordów - powinno jeszcze nieco przyspieszyć działanie.
2. Połącz sposób działania obu funkcji, tj. w pętli sprawdzaj ile rekordów jeszcze pozostało do dodania (COUNT(*) - _amount), następnie w pętli dodaj n rekordów, gdzie n to MIN(_amount, COUNT(*) - _amount). Dzięki temu powinno wykonywać zapytania dodania rekordów do czasu osiągnięcia wymaganej ilości. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 897 Pomógł: 40 Dołączył: 16.12.2003 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Dzięki.
Mam jeszcze info, że jedno z szybszych rozwiązań to zapisanie liczb do pliku tekstowego, a potem załadowanie ich używając LOAD DATA INFILE. I oczywiście należy usunąć (tymczasowo) indeksy, które są aktualizowane po każdym insercie. Ten post edytował czachor 13.06.2012, 14:12:19 -------------------- how many SEO experts does it take to change a light bulb,lightbulb,light,bulb,lamp,lighting,switch,sex,xxx
5-Reasons-why-you-should-NEVER-fix-a-computer-for-free |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 744 Pomógł: 118 Dołączył: 14.02.2009 Skąd: poziome Ostrzeżenie: (0%) ![]() ![]() |
Zrob tak jak pisze Crozin
czyli robisz dwie petle: pseldo kod zarys logiki
W php (szybko ale wymaga duzo pamieci)
Ten post edytował maly_swd 13.06.2012, 19:57:12 -------------------- śmieszne obrazki
Kryzys: Ser jem spleśniały, wino piję stare i samochód mam bez dachu.. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 207 Pomógł: 18 Dołączył: 4.09.2010 Skąd: warszawa Ostrzeżenie: (0%) ![]() ![]() |
a odwracając problem?
tworzysz tabelę zawierającą autoincrement w pełnym zadanym zakresie a losowanie realizujesz przez select z order by rand(), ew z limit order by rand() reklamowane jest jako niewydajne ale przy innodb z indeksem w ramie byłoby pewnie o rzędy szybkości szybsze niż te 33 godziny |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 744 Pomógł: 118 Dołączył: 14.02.2009 Skąd: poziome Ostrzeżenie: (0%) ![]() ![]() |
autoincrement nie jest ujemny, ale to nie problem aby obejsc;) wystarczy max(id)/2-id i mamy odpowiednia liczbe
-------------------- śmieszne obrazki
Kryzys: Ser jem spleśniały, wino piję stare i samochód mam bez dachu.. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 19.08.2025 - 20:30 |