Jak szybko powinienem oczekiwać, że PostGIS geokoduje dobrze sformatowane adresy?


17

Jak szybko powinienem oczekiwać, że PostGIS geokoduje dobrze sformatowane adresy?

Zainstalowałem PostgreSQL 9.3.7 i PostGIS 2.1.7, załadowałem dane narodu i wszystkie dane stanów, ale odkryłem, że geokodowanie jest znacznie wolniejsze niż się spodziewałem. Czy moje oczekiwania były zbyt wysokie? Otrzymuję średnio 3 indywidualne geokody na sekundę. Muszę zrobić około 5 milionów i nie chcę na to czekać trzy tygodnie.

To jest maszyna wirtualna do przetwarzania gigantycznych macierzy R i zainstalowałem tę bazę danych z boku, aby konfiguracja wyglądała trochę głupio. Jeśli poważna zmiana w konfiguracji maszyny wirtualnej pomoże, mogę zmienić konfigurację.

Specyfikacja sprzętu

Pamięć: 65 GB procesory: 6 lscpudaje mi to:

# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                6
On-line CPU(s) list:   0-5
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             6
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 58
Stepping:              0
CPU MHz:               2400.000
BogoMIPS:              4800.00
Hypervisor vendor:     VMware
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              30720K
NUMA node0 CPU(s):     0-5

OS to centos, uname -rvdaje to:

# uname -rv
2.6.32-504.16.2.el6.x86_64 #1 SMP Wed Apr 22 06:48:29 UTC 2015

Konfiguracja Postgresql

> select version()
"PostgreSQL 9.3.7 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11), 64-bit"
> select PostGIS_Full_version()
POSTGIS="2.1.7 r13414" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.2, released 2012/10/08" LIBXML="2.7.6" LIBJSON="UNKNOWN" TOPOLOGY RASTER"

Na podstawie wcześniejszych sugestii do tych typów kwerend, I podniósł shared_buffersw postgresql.confpliku do około 1/4 dostępnej pamięci RAM i skutecznej rozmiar pamięci podręcznej do 1/2 RAM:

shared_buffers = 16096MB     
effective_cache_size = 31765MB

Mam installed_missing_indexes()i (po rozwiązaniu zduplikowanych wstawek w niektórych tabelach) nie wystąpiły żadne błędy.

Przykład geokodowania SQL # 1 (partia) ~ średni czas wynosi 2,8 / s

Postępuję zgodnie z przykładem z http://postgis.net/docs/Geocode.html , w którym utworzyłem tabelę zawierającą adres do geokodu, a następnie wykonuję SQL UPDATE:

UPDATE addresses_to_geocode
              SET  (rating, longitude, latitude,geo) 
              = ( COALESCE((g.geom).rating,-1),
              ST_X((g.geom).geomout)::numeric(8,5), 
              ST_Y((g.geom).geomout)::numeric(8,5),
              geo )
              FROM (SELECT "PatientId" as PatientId
              FROM addresses_to_geocode 
              WHERE "rating" IS NULL ORDER BY PatientId LIMIT 1000) As a
              LEFT JOIN (SELECT "PatientId" as PatientId, (geocode("Address",1)) As geom
              FROM addresses_to_geocode As ag
              WHERE ag.rating IS NULL ORDER BY PatientId LIMIT 1000) As g ON a.PatientId = g.PatientId
              WHERE a.PatientId = addresses_to_geocode."PatientId";

Używam wielkości partii 1000 powyżej i zwraca ona za 337,70 sekund. Jest trochę wolniejszy dla mniejszych partii.

Przykład geokodowania SQL # 2 (rząd po rzędzie) ~ średni czas wynosi 1,2 / s

Kiedy kopie moje adresy, wykonując geokody pojedynczo z instrukcją, która wygląda tak (tak przy okazji, poniższy przykład zajął 4,14 sekundy),

SELECT g.rating, ST_X(g.geomout) As lon, ST_Y(g.geomout) As lat, 
    (addy).address As stno, (addy).streetname As street, 
    (addy).streettypeabbrev As styp, (addy).location As city, 
    (addy).stateabbrev As st,(addy).zip 
FROM geocode('6433 DROMOLAND Cir NW, MASSILLON, OH 44646',1) As g;

jest nieco wolniejszy (2,5x na rekord), ale mogę spojrzeć na rozkład czasów zapytań i zobaczyć, że jest to niewielka część długich zapytań, które najbardziej to spowalniają (tylko pierwsze 2600 z 5 milionów ma czasy wyszukiwania). Oznacza to, że górne 10% zajmuje średnio około 100 ms, dolne 10% średnio 3,69 sekundy, podczas gdy średnia wynosi 754 ms, a mediana wynosi 340 ms.

# Just some interaction with the data in R
> range(lookupTimes[1:2600])
[1]  0.00 11.54
> median(lookupTimes[1:2600])
[1] 0.34
> mean(lookupTimes[1:2600])
[1] 0.7541808
> mean(sort(lookupTimes[1:2600])[1:260])
[1] 0.09984615
> mean(sort(lookupTimes[1:2600],decreasing=TRUE)[1:260])
[1] 3.691269
> hist(lookupTimes[1:2600]

Czasy geokodowania dla pierwszych 2600 wierszy

Inne przemyślenia

Jeśli nie uda mi się zwiększyć wydajności o rząd wielkości, doszedłem do wniosku, że mogę przynajmniej zgadywać co do przewidywania wolnych czasów geokodów, ale nie jest dla mnie oczywiste, dlaczego wolniejsze adresy wydają się trwać dłużej. Korzystam z oryginalnego adresu w niestandardowym kroku normalizacji, aby upewnić się, że jest on ładnie sformatowany, zanim geocode()funkcja go uzyska

sql=paste0("select pprint_addy(normalize_address('",myAddress,"'))")

gdzie myAddressjest [Address], [City], [ST] [Zip]ciągiem skompilowanym z tabeli adresów użytkownika z bazy danych innej niż postgresql.

Próbowałem (nie udało się) zainstalować pagc_normalize_addressrozszerzenia, ale nie jest jasne, czy przyniesie to rodzaj ulepszenia, którego szukam. Edytowane w celu dodania informacji o monitorowaniu zgodnie z sugestią

Występ

Jeden procesor jest powiązany: [edytuj, tylko jeden procesor na zapytanie, więc mam 5 nieużywanych procesorów]

top - 14:10:26 up 1 day,  3:11,  4 users,  load average: 1.02, 1.01, 0.93
Tasks: 219 total,   2 running, 217 sleeping,   0 stopped,   0 zombie
Cpu(s): 15.4%us,  1.5%sy,  0.0%ni, 83.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  65056588k total, 64613476k used,   443112k free,    97096k buffers
Swap: 262139900k total,    77164k used, 262062736k free, 62745284k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 3130 postgres  20   0 16.3g 8.8g 8.7g R 99.7 14.2 170:14.06 postmaster
11139 aolsson   20   0 15140 1316  932 R  0.3  0.0   0:07.78 top
11675 aolsson   20   0  135m 1836 1504 S  0.3  0.0   0:00.01 wget
    1 root      20   0 19364 1064  884 S  0.0  0.0   0:01.84 init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.06 kthreadd

Próbka aktywności dysku na partycji danych, gdy jeden proces jest powiązany w 100%: [edycja: tylko jeden procesor jest używany przez to zapytanie]

# dstat -tdD dm-3 1
----system---- --dsk/dm-3-
  date/time   | read  writ
12-06 14:06:36|1818k 3632k
12-06 14:06:37|   0     0
12-06 14:06:38|   0     0
12-06 14:06:39|   0     0
12-06 14:06:40|   0    40k
12-06 14:06:41|   0     0
12-06 14:06:42|   0     0
12-06 14:06:43|   0  8192B
12-06 14:06:44|   0  8192B
12-06 14:06:45| 120k   60k
12-06 14:06:46|   0     0
12-06 14:06:47|   0     0
12-06 14:06:48|   0     0
12-06 14:06:49|   0     0
12-06 14:06:50|   0    28k
12-06 14:06:51|   0    96k
12-06 14:06:52|   0     0
12-06 14:06:53|   0     0
12-06 14:06:54|   0     0 ^C

Przeanalizuj ten SQL

To jest z EXPLAIN ANALYZEtego zapytania:

"Update on addresses_to_geocode  (cost=1.30..8390.04 rows=1000 width=272) (actual time=363608.219..363608.219 rows=0 loops=1)"
"  ->  Merge Left Join  (cost=1.30..8390.04 rows=1000 width=272) (actual time=110.934..324648.385 rows=1000 loops=1)"
"        Merge Cond: (a.patientid = g.patientid)"
"        ->  Nested Loop  (cost=0.86..8336.82 rows=1000 width=184) (actual time=10.676..34.241 rows=1000 loops=1)"
"              ->  Subquery Scan on a  (cost=0.43..54.32 rows=1000 width=32) (actual time=10.664..18.779 rows=1000 loops=1)"
"                    ->  Limit  (cost=0.43..44.32 rows=1000 width=4) (actual time=10.658..17.478 rows=1000 loops=1)"
"                          ->  Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode addresses_to_geocode_1  (cost=0.43..195279.22 rows=4449758 width=4) (actual time=10.657..17.021 rows=1000 loops=1)"
"                                Filter: (rating IS NULL)"
"                                Rows Removed by Filter: 24110"
"              ->  Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode  (cost=0.43..8.27 rows=1 width=152) (actual time=0.010..0.013 rows=1 loops=1000)"
"                    Index Cond: ("PatientId" = a.patientid)"
"        ->  Materialize  (cost=0.43..18.22 rows=1000 width=96) (actual time=100.233..324594.558 rows=943 loops=1)"
"              ->  Subquery Scan on g  (cost=0.43..15.72 rows=1000 width=96) (actual time=100.230..324593.435 rows=943 loops=1)"
"                    ->  Limit  (cost=0.43..5.72 rows=1000 width=42) (actual time=100.225..324591.603 rows=943 loops=1)"
"                          ->  Index Scan using "addresses_to_geocode_PatientId_idx" on addresses_to_geocode ag  (cost=0.43..23534259.93 rows=4449758000 width=42) (actual time=100.225..324591.146 rows=943 loops=1)"
"                                Filter: (rating IS NULL)"
"                                Rows Removed by Filter: 24110"
"Total runtime: 363608.316 ms"

Zobacz lepszy podział na http://explain.depesz.com/s/vogS


1
Co robi maszyna po uruchomieniu zapytań? Czy to blokuje IO, czy też wąskie gardło gdzie indziej?
til_b

1
Ile stanów załadowałeś. Zwykle dostaję od 30 ms do 150 ms na adres w 64-bitowym systemie Windows z ram 4-8 GB. Zwykle jednak pracuję tylko z 1 lub 2 stanami. Nie wykonano testu porównawczego dotyczącego wpływu większej liczby stanów na wydajność.
LR1234567

@ LR1234567 50 stanów
aaryno

1
@til_b Procesor jest ustawiony na 99,7%
aaryno

Wygląda na to, że będziemy musieli poczekać kilka tygodni, aby ukończyć to zadanie, ponieważ jest to jednorazowa sprawa i że pozostanie nam dużo soku, gdy wszystko będzie gotowe, aby nadążyć za obciążeniem 100 adresów dziennie my doświadczamy. Pozostawię to otwarte, dopóki nie skończymy, na wypadek, gdyby pojawiło się coś naprawdę przekonującego, co pozwoli nam obejść nasze ustalone procesory.
aaryno

Odpowiedzi:


7

Spędziłem dużo czasu eksperymentując z tym, myślę, że lepiej pisać osobno, ponieważ są one z innej perspektywy.

To naprawdę skomplikowany temat, więcej szczegółów w moim poście na blogu na temat konfiguracji serwera geokodowania i skryptu, którego użyłem . Oto kilka krótkich streszczeń:

Serwer z tylko 2 danymi stanów jest zawsze szybszy niż serwer załadowany wszystkimi danymi 50 stanów.

Sprawdziłem to na moim komputerze domowym w różnym czasie i na dwóch różnych serwerach Amazon AWS.

Mój darmowy serwer warstwy AWS z danymi 2 stanów ma tylko 1G RAM, ale ma spójną wydajność 43 ~ 59 ms dla danych z 1000 rekordów i 45 000 rekordów.

Użyłem dokładnie tej samej procedury konfiguracji dla serwera AWS 8G RAM z załadowanymi wszystkimi stanami, dokładnie tym samym skryptem i danymi, a wydajność spadła do 80 ~ 105 ms.

Moja teoria jest taka, że ​​gdy geokoder nie może dokładnie dopasować adresu, zaczął rozszerzać zakres wyszukiwania i ignorować niektóre elementy, takie jak kod pocztowy lub miasto. Dlatego dokument geokodowy może pochwalić się tym, że może ponownie skolonizować adres przy użyciu nieprawidłowego kodu pocztowego, chociaż zajęło to 3000 ms.

Po załadowaniu danych tylko z 2 stanów serwer zajmie znacznie mniej czasu w bezowocnym wyszukiwaniu lub dopasowaniu z bardzo niskim wynikiem, ponieważ może wyszukiwać tylko w 2 stanach.

Próbowałem to ograniczyć, ustawiając restrict_regionparametr na stan wieloboków w funkcji geokodu, mając nadzieję, że uniknie to bezowocnego wyszukiwania, ponieważ jestem pewien, że większość adresów ma poprawny stan. Porównaj te dwie wersje:

  select geocode('501 Fairmount DR , Annapolis, MD 20137',1); 
  select geocode('501 Fairmount DR , Annapolis, MD 20137', 1, the_geom) from tiger.state where statefp = '24';

Jedyną różnicą wprowadzoną przez drugą wersję jest to, że normalnie, jeśli ponownie uruchomię to samo zapytanie, będzie to znacznie szybsze, ponieważ powiązane dane zostały zapisane w pamięci podręcznej, ale druga wersja wyłączyła ten efekt.

Więc restrict_regionnie działa tak, jak chciałem, może po prostu został użyty do filtrowania wyniku wielokrotnego trafienia, a nie do ograniczenia zakresów wyszukiwania.

Możesz trochę dostroić swój postgre conf.

Zwykły podejrzany o brakujące indeksy instalacji, analiza próżniowa nie zrobiły dla mnie żadnej różnicy, ponieważ skrypt pobierania wykonał już niezbędną konserwację, chyba że się z nimi pomyliłeś.

Jednak ustawienie postgre conf zgodnie z tym postem pomogło. Mój serwer w pełnej skali z 50 stanami miał 320 ms z domyślną konfiguracją dla niektórych gorszych danych, poprawił się do 185 ms z buforowaniem 2G shared_buffer, 5G pamięci podręcznej i poszedł do 100 ms dalej z większością ustawień dostosowanych do tego postu.

Jest to bardziej odpowiednie dla postgis, a ich ustawienia wydawały się podobne.

Wielkość partii każdego zatwierdzenia nie miała większego znaczenia dla mojej sprawy. W dokumentacji geokodu użyto wielkości partii 3. Eksperymentowałem z wartościami od 1, 3, 5 do 10. Nie znalazłem z tym żadnej znaczącej różnicy. Przy mniejszym rozmiarze partii wprowadzasz więcej zmian i aktualizacji, ale myślę, że prawdziwej szyjki butelki nie ma tutaj. Właściwie używam teraz wielkości partii 1. Ponieważ zawsze pojawia się jakiś nieoczekiwany źle sformatowany adres spowoduje wyjątek, ustawię całą partię z błędem jako ignorowaną i przejdę do pozostałych wierszy. Przy wielkości partii 1 nie muszę przetwarzać tabeli po raz drugi, aby geokodować możliwe dobre rekordy w partii oznaczonej jako ignorowane.

Oczywiście zależy to od sposobu działania skryptu wsadowego. Później opublikuję mój skrypt ze szczegółami.

Możesz spróbować użyć znormalizowanego adresu, aby odfiltrować zły adres, jeśli pasuje do twojego zastosowania. Widziałem gdzieś o tym wspominał, ale nie byłem pewien, jak to działa, ponieważ funkcja normalizacji działa tylko w formacie, nie może tak naprawdę powiedzieć, który adres jest nieprawidłowy.

Później zdałem sobie sprawę, że jeśli adres jest w oczywisty sposób złym stanie i chcesz je pominąć, może to pomóc. Na przykład w wielu adresach brakuje nazwy ulicy, a nawet nazwy ulicy. Normalizacja wszystkich adresów najpierw będzie względnie szybka, następnie możesz odfiltrować dla ciebie oczywisty zły adres, a następnie je pominąć. Nie odpowiadało to jednak mojemu użytkowaniu, ponieważ adres bez numeru ulicy, a nawet nazwy ulicy nadal można zmapować na ulicę lub miasto, a ta informacja wciąż jest dla mnie przydatna.

I większość adresów, które nie mogą być geokodowane w moim przypadku, faktycznie mają wszystkie pola, po prostu nie ma zgodności w bazie danych. Nie można filtrować tych adresów tylko poprzez ich normalizację.

EDYCJA Aby uzyskać więcej informacji, zobacz mój wpis na blogu na temat konfiguracji serwera geokodowania i skryptu, którego użyłem .

EDYCJA 2 Skończyłem geokodowanie 2 milionów adresów i dużo wyczyściłem adresy oparte na wyniku geokodowania. Dzięki lepiej oczyszczonemu wejściowi następne zadanie wsadowe działa znacznie szybciej. Przez czysty rozumiem, że niektóre adresy są oczywiście błędne i powinny zostać usunięte, lub mieć nieoczekiwaną zawartość, aby geokoder mógł powodować problemy z geokodowaniem. Moja teoria jest taka: usunięcie złych adresów może uniknąć zepsucia pamięci podręcznej, co znacznie poprawia wydajność dobrych adresów.

Oddzieliłem dane wejściowe w zależności od stanu, aby upewnić się, że każde zadanie może mieć wszystkie dane potrzebne do geokodowania w pamięci podręcznej. Jednak każdy zły adres w pracy zmusza geokoder do wyszukiwania w większej liczbie stanów, co może zepsuć pamięć podręczną.


Świetna odpowiedź. Na moim urządzeniu filtrowanie według stanu przyspiesza dopasowanie o około 50 (!), Ale podejrzewam, że mogę mieć problemy z indeksem.
ako

2
  1. Zgodnie z tym wątkiem do dyskusji powinieneś zastosować tę samą procedurę normalizacji do przetwarzania danych Tiger i adresu wejściowego. Ponieważ dane Tiger zostały przetworzone za pomocą wbudowanego normalizatora, lepiej używać tylko wbudowanego normalizatora. Nawet jeśli uruchomiłeś pagc_normalizer, może ci to nie pomóc, jeśli nie użyjesz go do aktualizacji danych Tiger.

    Biorąc to pod uwagę, myślę, że geocode () i tak wywoła normalizator, więc normalizacja adresu przed geokodowaniem może być naprawdę nieprzydatna. Jednym z możliwych zastosowań normalizatora może być porównanie znormalizowanego adresu i adresu zwróconego przez geocode (). Po ich znormalizowaniu łatwiej byłoby znaleźć niewłaściwy wynik geokodowania.

    Jeśli możesz odfiltrować zły adres z geokodu za pomocą normalizatora, to naprawdę pomoże. Jednak nie widzę, aby normalizator miał coś takiego jak wynik meczu lub ocena.

  2. W tym samym wątku dyskusyjnym wspomniano również o przełączniku debugowania, geocode_addressaby wyświetlić więcej informacji. Węzeł geocode_addresswymaga znormalizowanego wprowadzania adresu.

  3. Geocoder jest szybki do dokładnego dopasowania, ale w trudnych przypadkach zajmuje dużo więcej czasu. Odkryłem, że istnieje parametr restrict_regioni pomyślałem, że może ograniczy to bezowocne wyszukiwanie, jeśli ustawię limit jako stan, ponieważ jestem całkiem pewien, w jakim stanie. Okazało się, że ustawienie go na zły stan nie zatrzymało geokodu, aby uzyskać poprawny adres, choć zajmuje to trochę czasu.

    Więc może geokoder będzie szukał we wszystkich możliwych miejscach, jeśli pierwsze dokładne wyszukiwanie nie będzie pasować. Dzięki temu jest w stanie przetwarzać dane wejściowe z pewnymi błędami, ale także spowalnia niektóre wyszukiwanie.

    Myślę, że dobrze jest, aby usługa interaktywna akceptowała dane wejściowe z błędami, ale czasami możemy chcieć zrezygnować z małego zestawu złego adresu, aby uzyskać lepszą wydajność w geokodowaniu wsadowym.


Jaki wpływ miał restrict_regionczas na ustawienie prawidłowego stanu? Ponadto z wątku użytkowników postgis, do którego link prowadziłeś powyżej, wspominają oni konkretnie o problemach z adresami, takimi jak te, 1020 Highway 20które napotkałem.
aaryno

Ustawienie prawidłowego stanu prawdopodobnie nie ulegnie poprawie, ponieważ jeśli adres jest dobrze sformatowany, geokoder może i tak uzyskać prawidłowy stan.
dracodoc

1

Zamierzam opublikować tę odpowiedź, ale mam nadzieję, że inny autor pomoże w rozbiciu następujących, co, jak sądzę, pozwoli nam stworzyć bardziej spójny obraz:

Jaki jest wpływ liczby stanów załadowanych na geokodowanie? Mam wszystkie 50 i widzę znacznie niższą wydajność niż @ LR1234567 (tj. 8x czas na geocode).

Jaka jest najbardziej wydajna metoda geokodowania zbiorczego? Prowadzę proces szeregowy, powtarzając partie po 100, aż do zakończenia całego backloadu. Preferowane byłoby podejście wielowątkowe, ale jakie podejścia są zalecane?

Jaki wpływ ma wirtualizacja na geokodowanie PostgreSQL? Zgaduję 10% na podstawie niektórych innych postów, ale nie mam pewności co do tej odpowiedzi

Teraz moja odpowiedź, która jest tylko anegdotą:

Najlepsze, jakie otrzymuję (w oparciu o pojedyncze połączenie) to średnio 208 ms na geocode. Mierzy się to poprzez losowe wybieranie adresów z mojego zbioru danych, który obejmuje całe USA. Zawiera niektóre brudne dane, ale najdłużej działające geocodenie wydają się złe w oczywisty sposób.

Istotą tego jest to, że wydaje się, że jestem związany z procesorem i że pojedyncze zapytanie jest powiązane z jednym procesorem. Mogę to zrównoleglić, mając wiele połączeń działających z teoretycznie UPDATEna uzupełniających się segmentach addresses_to_geocodetabeli. W międzyczasie geocodezabieram średnio 208 ms na zbiór danych w całym kraju. Dystrybucja jest zniekształcona zarówno pod względem tego, gdzie znajduje się większość moich adresów, jak i pod względem czasu, jaki zajmują (np. Patrz histogram powyżej) oraz poniższej tabeli.

Moje najlepsze podejście do tej pory polega na robieniu tego w partiach po 10000 sztuk, z pewną możliwą do oszacowania poprawą dzięki większej wydajności na partię. Dla partii 100 otrzymywałem około 251ms, przy 10000 dostaję 208ms.

UPDATE addresses_to_geocode 
SET (rating, longitude, latitude, geo) = 
   (COALESCE((g.geom).rating,-1), 
            ST_X((g.geom).geomout)::numeric(8,5),   
            ST_Y((g.geom).geomout)::numeric(8,5), 
            geo) 
   FROM (
       SELECT "PatientId" as PatientId 
       FROM addresses_to_geocode  
       WHERE "rating" IS NULL 
       ORDER BY PatientId LIMIT 100) As a 
   LEFT JOIN (
       SELECT "PatientId" as PatientId, (geocode("Address",1)) As geom 
       FROM addresses_to_geocode As ag 
       WHERE ag.rating IS NULL 
       ORDER BY PatientId LIMIT 100) As g 
   ON a.PatientId = g.PatientId 
   WHERE a.PatientId = addresses_to_geocode."PatientId";

Muszę zacytować nazwy pól, ponieważ RPostgreSQL tworzy tabele dbWriteTable

To około 4x tak szybko, jakbym nagrywał jedną płytę na raz. Kiedy robię je pojedynczo, mogę uzyskać podział według stanu (patrz poniżej). Zrobiłem to, aby sprawdzić, czy jeden lub więcej stanów TIGER ma złe obciążenie lub indeks, co, jak się spodziewałem, spowoduje geocodepogorszenie wydajności. Mam oczywiście złe dane (niektóre adresy to nawet adresy e-mail!), Ale większość z nich jest dobrze sformatowana. Jak powiedziałem wcześniej, niektóre z najdłużej działających zapytań nie mają oczywistych braków w swoim formacie. Poniżej znajduje się tabela liczbowa, minimalny czas zapytania, średni czas zapytania i maksymalny czas zapytania dla stanów z 3000 - niektóre losowe adresy z mojego zestawu danych:

       state   n  min      mean   max
1          .   1 0.00 0.0000000  0.00
12        DC   6 0.07 0.0900000  0.10
9  CHIHUAHUA   1 0.16 0.1600000  0.16
2         00   1 0.18 0.1800000  0.18
6         AR   1 0.37 0.3700000  0.37
27        MT  17 0.14 0.4229412  1.01
14        GA  37 0.22 0.4340541  2.78
10        CO   1 0.54 0.5400000  0.54
16        IL 390 0.16 0.5448974  3.75
8         CA 251 0.17 0.5546614  3.58
5         AL   4 0.13 0.5575000  0.86
18        KS   3 0.43 0.5966667  0.75
23        ME 121 0.14 0.6266116  7.88
35        SC 390 0.14 0.6516923  6.88
24        MI  62 0.12 0.6524194  3.36
40        WA   3 0.23 0.7500000  1.41
32        OK 145 0.17 0.7538621  5.84
20        LA   1 0.76 0.7600000  0.76
31        OH 551 0.00 0.7623775 10.27
17        IN 108 0.19 0.7864815  3.64
43      <NA>  89 0.00 0.8152809  4.98
15        IA   1 0.82 0.8200000  0.82
30        NY 227 0.19 0.8227753 28.47
19        KY   3 0.56 0.8333333  1.36
36        TN 333 0.11 0.8566667  6.45
28        NC 129 0.24 0.8843411  4.07
13        FL  70 0.28 0.9131429  4.65
7         AZ 101 0.20 0.9498020  6.33
34        PA  56 0.14 0.9594643  3.61
29        NJ   1 1.03 1.0300000  1.03
33        OR 101 0.24 1.0966337 14.89
26        MS  28 0.25 1.1503571 11.89
3          9   6 0.58 1.2133333  1.93
4         AK   1 1.25 1.2500000  1.25
22        MD   9 0.50 1.3055556  4.17
25        MO  22 0.31 1.3381818  4.20
42        WY   1 1.38 1.3800000  1.38
38        VA 127 0.20 1.3873228  5.69
37        TX   4 0.53 1.4800000  3.28
21        MA   4 0.47 1.5725000  3.63
11        CT   5 0.38 1.6760000  4.68
39        VT   1 2.25 2.2500000  2.25
41        WI   2 2.27 2.2850000  2.30
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.