2011-01-21 17 views
9

Próbuję trochę eksperymentować z przesuwaniem zestawu danych, który nie jest geo-przestrzenny, ale pasuje do niego całkiem dobrze i jestem pewien, że wyniki są nieco niepokojące. Zbiór danych to dane genetyczne np. Ludzki genom, w którym mamy region DNA, gdzie elementy takie jak geny zajmują określone współrzędne początku i końca (nasza oś X). Mamy wiele regionów DNA (chromosomy), które zajmują oś Y. Celem jest przywrócenie wszystkich elementów, które przecinają dwie współrzędne X wzdłuż jednej współrzędnej Y, np. LineString (START 1, END 2).Słaba wydajność przy korzystaniu z indeksów przestrzennych w MySQL

Teoria wydawała dźwięk więc pchnął go do istniejącego MySQL oparty Genome Project i wymyślił struktury tabeli, takich jak:

CREATE TABLE `spatial_feature` (
    `spatial_feature_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `external_id` int(10) unsigned NOT NULL, 
    `external_type` int(3) unsigned NOT NULL, 
    `location` geometry NOT NULL, 
    PRIMARY KEY (`spatial_feature_id`), 
    SPATIAL KEY `sf_location_idx` (`location`) 
) ENGINE=MyISAM; 

external_id reprezentuje identyfikator podmiotu mamy zakodowaną w tej tabeli & external_type koduje źródło tego. Wszystko wyglądało dobrze i wprowadziłem wstępne dane (30 000 wierszy), które wydawały się dobrze działać. Kiedy ten wzrost przekroczył 3 miliony wierszy znak MySQL odmówił użycia indeksu przestrzennego i był wolniejszy, gdy był zmuszony do użycia go (40 sekund vs. 5 sekund przy użyciu pełnego skanowania tabeli). Po dodaniu większej ilości danych indeks zaczął być używany, ale kara za wyniki nadal występowała. Wymuszenie wyłączenia indeksu spowodowało zmniejszenie liczby zapytań do 8 sekund. Zapytanie używam wygląda następująco:

select count(*) 
from spatial_feature 
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location); 

dane wchodząc to być bardzo gęsta wzdłuż wymiarów Y (myśleć o tym, jakbyś nagrał pozycję każdego budynku, budka telefoniczna, skrzynki pocztowej i gołąb na bardzo długiej drodze). Zrobiłem testy, w jaki sposób R-Indexes zachowują się z tymi danymi w Javie, a także inni w terenie, z powodzeniem zastosowali je do formatów płaskich. Jednak nikt nie zastosował ich do baz danych AFAIK, które są celem tego testu.

Czy ktoś nie zaobserwował podobnego zachowania podczas dodawania dużych ilości danych do modelu przestrzennego, który nie jest bardzo rozbieżny wzdłuż konkretnej osi? Problem będzie występował, jeśli odwrócę użycie współrzędnych. Biegnę następującą konfigurację jeśli to jest przyczyną

  • MacOS 10.6.6
  • MySQL 5.1.46

Pomoc!

przynosząc również w wyjaśnić planu w

+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+ 
| id | select_type | table   | type | possible_keys | key | key_len | ref | rows | filtered | Extra  | 
+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+ 
| 1 | SIMPLE  | spatial_feature | ALL | sf_location_idx | NULL | NULL | NULL | 3636060 | 33.33 | Using where | 
+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+ 
1 row in set, 1 warning (0.00 sec) 

Ponowne napisany SQL wygląda następującym

select count(0) AS `count(*)` from `arabidopsis_thaliana_core_7_60_9`.`spatial_feature` where intersects(geometryfromtext('LineString(7420023 1, 7420023 1)'),`arabidopsis_thaliana_core_7_60_9`.`spatial_feature`.`location`) 

Nadal nie podkreślając dlaczego wydajność tego zapytania jest tak słaba

Po przeczytaniu artykuł opublikowany przez @Fraser z rickonrails wydaje się, że problem polega tylko na tym, że indeks nie jest w pamięci. Jeśli zastosuję podobne techniki do tych wymienionych w artykule (co czyni bardzo istotnym buforem klucza), a następnie zmuszam zapytanie do korzystania z indeksu zapytań czasowych. Nadal mamy do czynienia z opóźnieniem między zapytaniem o region &, a następnie wyszukaniem podzbioru regionu, ale wszystko wskazuje na to, że ładowanie indeksów jest prawidłowe.

Jaki jest morał tej historii? Indeksy R w MySQL mają dość słabą wydajność, dopóki nie są w pamięci, a następnie mają doskonałą wydajność.Naprawdę nie jest to dobre rozwiązanie dla tego, co chciałem zrobić z nimi, ale nadal zapewnia interesujący kąt w MySQL.

Dzięki za pomoc wszystkim.

+0

można uzyskać odpowiedź na http://gis.stackexchange.com – dassouki

+0

Cheers za info zrobi post również tam – andeyatz

+0

można dodawać wyniki tej kwerendy: wytłumaczyć rozszerzony select count (*) from spatial_feature gdzie MBRIntersects (GeomFromText ('LineString (7420023 1, 7420023 1)'), lokalizacja); To pokazałoby, jak MySQL go wykonuje. To może uwypuklić wąskie gardło. –

Odpowiedz

0

Celem jest, aby przywrócić wszystkie elementy, które przecinają dwie współrzędne X wzdłuż jednej Y koordynować

Czy można uznać za pomocą rozumu indeksu wiele pól? Jak:

CREATE INDEX spacial_search ON spatial_feature(y, x) 

Jeśli pracujesz z ograniczonego zestawu y wartości to jest droga do.

0

Mam dyplom z genetyki i jestem programistą, nie musisz używać X i Y, ponieważ twoja nomenklatura będzie zbyt faffy ... potrzebujesz pozycji startowej i zatrzymania pozycja (nie jest "oś") i numer chromosomu . Najpierw indeksujesz przez liczbę chromosomów, następnie pozycję, a następnie indeksujesz pozycję, a następnie chromosom. (Pytanie: Czy do czynienia w eukariontów lub chromosomach, które mogą mieć dwie ramki odczytu?)

EG: (gdzie „x” = pozycja i „y” = chromosom)

CREATE INDEX spatial_index_1 ON spatial_feature(chromosome, position); 
CREATE INDEX spatial_index_2 ON spatial_feature(position, chromosome); 

Nawiasem mówiąc Chromosomy są bardzo długie ciągi (podobnie jak dane) możesz (przyspieszyć przesuwanie ich jako takie, jak bloby (tj. kodujące geny i śmieciowe DNA)

+0

Próbowałem uprościć sprawę nieco bardziej, aby spróbować osiągnąć dużo publiczność w nadziei, że jest to coś, co my bioinformatyści zrobiliśmy źle.Wydaje się, że problem polega nie na tworzeniu indeksu przestrzennego, który pozwala na tego typu wyszukiwanie (w tej dziedzinie użyłem tej samej techniki do wielkiego sukcesu). Bardziej możliwe jest użycie przestrzennych rozszerzeń MySQL. Wygląda na to, że pomimo tego, że potrafią one przewyższać wszelkie indeksowania dla tego typu danych (binning, linear index lub max feature size), indeks * musi * być w pamięci. To jest breaker jeśli masz 2300 DB na 1 serwerze – andeyatz

+1

MySQL jest skompilowany z pewnymi "domyślnymi", jeśli jesteś odważny i czujesz, że możesz zejść w dół tej króliczej dziury, są faceci forge.mysql .. możesz skompilować mysql do słuchaj pewnej mechaniki .. to twardy rdzeń, ale może warto. http://forge.mysql.com/wiki/Top10SQLPerformanceTips – conners

+0

również http://planet.mysql.com/ – conners

1

Z planszy EXPLAIN widzimy, że chociaż spatial może być użyty do zapytania ("possible_keys" kolumna), nie jest używana (wartość NULL w kolumnie "klucz") Nie wiem, dlaczego nie została wybrana automatycznie, ale można jawnie wpisać truct MySql użyć indeksu, określając je w zapytaniu za pomocą indeksu „siła” klauzuli:

select count(*) 
from spatial_feature 
force index (sf_location_idx) -- <== this is the 'force index' clause 
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location); 
+0

BTW, mój Wersja mysql to 5.5 – Amnon

+0

To jest odpowiedź, którą też myślałem. W starszych wersjach MySQL wiem, że podpowiedzi do indeksów nie zawsze robią to, czego się spodziewałem - nie jestem pewien, czy ta usterka była w implementacji lub moich oczekiwaniach, ale byłoby ciekawie sprawdzić, czy to działa dla OP. – ratsbane

0

Czy jesteś pewien, relacyjna baza danych jest do zrobienia? Gdybym był tobą, chciałbym popchnąć twoje zbiory danych do Solr lub Elastic Search (prawdopodobnie przechowując główne zbiory danych w innym miejscu). Te silniki są zbudowane do indeksowania, zauważysz różnicę w czasie odpowiedzi.

Powiązane problemy