2011-01-21 14 views
9

Sto provando un piccolo esperimento per spingere un set di dati che non è geo-spaziale, ma si adatta abbastanza bene e sto trovando i risultati un po 'inquietanti. Il set di dati è dati genomici ad es. il Genoma Umano dove abbiamo una regione di DNA in cui elementi come i geni occupano specifiche coordinate di inizio e fine (il nostro asse X). Abbiamo più regioni di DNA (cromosomi) che occupano l'asse Y. L'obiettivo è di riportare tutti gli elementi che intersecano due coordinate X lungo una singola coordinata Y, ad es. LineString (START 1, END 2).Scarse prestazioni quando si utilizzano indici spaziali in MySQL

La teoria sembrava suono così ho spinto in un progetto esistente genoma MySQL based e si avvicinò con una struttura di tabella del tipo:

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 rappresenta l'identificativo del soggetto che abbiamo codificato in questa tabella & external_type codifica la fonte di questo. Tutto sembrava a posto e ho inserito alcuni dati preliminari (30.000 righe) che sembravano funzionare bene. Quando è aumentato oltre il marchio di 3 milioni di righe, MySQL ha rifiutato di utilizzare l'indice spaziale ed è stato più lento quando è stato costretto a utilizzarlo (40 secondi contro 5 secondi utilizzando una scansione completa della tabella). Quando sono stati aggiunti più dati, è stato utilizzato l'indice, ma la penalizzazione delle prestazioni persisteva. La forzatura dell'indice non ha portato la query a 8 secondi. La query sto usando assomiglia:

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

I dati che vanno in questo è essere molto denso lungo le dimensioni Y (si pensi a come avete registrato la posizione di ogni edificio, cabina telefonica, casella postale e piccione su una strada molto lunga). Ho fatto dei test su come gli R-Indexes si comportano con questi dati in Java così come altri sul campo li hanno applicati a formati di file flat con successo. Tuttavia nessuno li ha applicati ai database AFAIK che è l'obiettivo di questo test.

Qualcuno ha notato un comportamento simile quando aggiunge grandi quantità di dati a un modello spaziale che non è molto disparato lungo un particolare asse? Il problema persiste se inverto l'utilizzo delle coordinate. Io corro la seguente configurazione, se questo è una causa

  • MacOS 10.6.6
  • MySQL 5.1.46

Aiuto!

portando anche a spiegare piano in

+----+-------------+-----------------+------+-----------------+------+---------+------+---------+----------+-------------+ 
| 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) 

Lo SQL riscritto è simile al seguente

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`) 

Ancora non mettendo in evidenza il motivo per cui le prestazioni di questa query è così povero

Dopo aver letto il articolo pubblicato da @Fraser dal rickonrails sembra che il problema abbia a che fare con l'indice non essendo in memoria. Se applico tecniche simili a quelle menzionate nell'articolo (rendendo molto importante il buffer delle chiavi) e poi imposto la query per utilizzare la query di indice per le piumette. Continuiamo a vedere un ritardo tra l'interrogazione di una regione &, quindi la ricerca di un sottoinsieme della regione, ma sta puntando tutto sul corretto caricamento degli indici.

Qual è la morale della storia? Gli R-Index in MySQL hanno prestazioni piuttosto scadenti finché non sono in memoria e quindi hanno prestazioni eccellenti.Non è davvero una buona soluzione per quello che volevo fare con loro, ma offre comunque un angolo interessante su MySQL.

Grazie per tutto il personale di supporto.

+0

si potrebbe ottenere una risposta alla http://gis.stackexchange.com – dassouki

+0

Applausi per informazioni faranno un post su là pure – andeyatz

+0

Puoi pubblicare risultati di questa query: spiegare estesa select count (*) da funzionalità spaziale dove MBRIntersects (GeomFromText ('LineString (7420023 1, 7420023 1)'), posizione); Questo mostrerebbe come MySQL lo sta eseguendo. Ciò potrebbe evidenziare il collo di bottiglia. –

risposta

0

L'obiettivo è quello di riportare tutti gli elementi che si intersecano due X coordinate lungo un unico Y coordinare

Hai pensato di usare uno spirito di indice più campi? Come:

CREATE INDEX spacial_search ON spatial_feature(y, x) 

Se si sta lavorando con una serie limitata di y valori questo è il modo per.

0

Ho una laurea in Genetica e sono un programmatore, non è necessario utilizzare X e Y come nomenclatura, sarà troppo debole ... è necessario un punto di inizio e uno stop posizione (non un "asse") e un numero di cromosoma. Indichi prima il numero cromosomico quindi la posizione e poi indichi la posizione del cromosoma. (Domanda: si occupa di eucarioti o cromosomi che possono avere due fasi di lettura?)

EG: (dove "x" = posizione e "y" = cromosoma)

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

inciso I cromosomi sono molto lunghi stringhe (proprio come i dati) è possibile (per accelerare le cose scaricarle come blob (cioè codifica di geni e DNA spazzatura)

+0

Stavo tentando di semplificare un po 'di più il problema per cercare di raggiungere un grande pubblico nella speranza che sia qualcosa che noi bioinformatici abbiamo sbagliato.Sembra che il problema non sia la creazione di un indice spaziale che consenta questo tipo di ricerca (ho applicato la stessa tecnica nella memoria di programmazione con grande successo). Più è possibile usare le estensioni spaziali di MySQL. Sembra anche che possano sovraperformare qualsiasi tipo di indicizzazione per questo tipo di dati (binning, indice lineare o dimensione massima della feature) che l'indice * deve * essere in memoria. Questo è un problema se hai 2300 DB su 1 server – andeyatz

+1

MySQL è compilato con alcune "impostazioni predefinite" se sei coraggioso e ti senti capace di andare in questa tana di coniglio ci sono i ragazzi di forge.mysql .. puoi compilare mysql do obbedire a determinati meccanismi .. è un hard core ma potrebbe valerne la pena http://forge.mysql.com/wiki/Top10SQLPerformanceTips – conners

+0

anche http://planet.mysql.com/ – conners

1

Dal piano EXPLAIN vediamo che, sebbene lo spazio possa essere utilizzato per la query ('possibili_keys' colonna), non viene utilizzato (NULL nella colonna 'chiave'). Non sono sicuro del motivo per cui non viene selezionato automaticamente, ma è possibile inserire in modo esplicito truct MySql utilizzare l'indice specificando che nella query utilizzando un 'indice di forza' clausola:

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, my la versione di mysql è 5.5 – Amnon

+0

Questa è la risposta che stavo pensando anche io. So che nelle versioni precedenti di MySQL i suggerimenti sugli indici non sempre facevano quello che mi aspettavo - non sono sicuro se quell'errore fosse nell'implementazione o nelle mie aspettative, ma sarebbe interessante vedere se questo funziona per l'OP. – ratsbane

0

Sei sicuro un database relazionale è la strada da percorrere? Se fossi in te, guarderei i tuoi set di dati su Solr o Ricerca elastica (probabilmente memorizzando i set di dati master altrove). Questi motori sono progettati per l'indicizzazione, noterai la differenza nei tempi di risposta.

Problemi correlati