2011-01-21 4 views
9

J'essaie d'expérimenter un ensemble de données qui n'est pas géospatial mais qui convient assez bien et qui trouve les résultats quelque peu déstabilisants. L'ensemble de données est des données génomiques, par ex. le génome humain où nous avons une région d'ADN où des éléments comme les gènes occupent des coordonnées de début et de fin spécifiques (notre axe X). Nous avons plusieurs régions d'ADN (chromosomes) qui occupent l'axe Y. Le but est de ramener tous les éléments qui coupent deux coordonnées X le long d'une seule coordonnée Y, par ex. LineString (START 1, END 2).Mauvaises performances lors de l'utilisation des index spatiaux dans MySQL

La théorie que je le son semblait si poussé dans un projet de génome à base de MySQL existant et est venu avec une structure de table comme:

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 représente l'identifiant de l'entité que nous avons codé dans ce tableau & external_type code la source de ceci. Tout avait l'air bien et j'ai poussé quelques données préliminaires (30 000 lignes) qui semblaient bien fonctionner. Quand cela dépassait la marque des 3 millions de lignes, MySQL refusait d'utiliser l'index spatial et était plus lent quand il était forcé de l'utiliser (40 secondes contre 5 secondes en utilisant un balayage de table complet). Lorsque plus de données ont été ajoutées, l'index a commencé à être utilisé, mais la pénalité de performance a persisté. Le forçage de l'index a ramené la requête à 8 secondes. La requête J'utilise ressemble:

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

Les données vont dans c'est être très dense le long des dimensions Y (pensez comme vous avez enregistré la position de chaque bâtiment, cabine téléphonique, boîte postale et pigeon sur une très longue route). J'ai fait des tests sur la façon dont les index R se comportent avec ces données en Java ainsi que d'autres dans le domaine les ont appliqués avec succès aux formats de fichiers plats. Cependant personne ne les a appliquées aux bases de données AFAIK qui est l'objectif de ce test.

Quelqu'un at-il vu là-bas un comportement similaire lors de l'ajout de grandes quantités de données à un modèle spatial qui est pas très disparate selon un axe particulier? Le problème persiste si j'inverse l'utilisation des coordonnées. Je cours la configuration suivante si c'est une cause

  • Mac OS 10.6.6
  • MySQL 5.1.46

Aide!

également mettre en expliquer plan

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

Le SQL réécrite ressemble à ce qui suit

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

Pas encore souligner pourquoi la performance de cette requête est si pauvre

Après avoir lu la article publié par @Fraser de rickonrails il semble que le problème est tout à voir avec l'index ne pas être en mémoire. Si j'applique des techniques similaires à celles mentionnées dans l'article (rendant le tampon de clé très grand en effet) et que je forcerai alors la requête à utiliser les temps de requête de l'index plumet. Nous observons toujours un décalage entre l'interrogation d'une région & puis la recherche d'un sous-ensemble de la région, mais tout indique que la charge des index est correcte.

Quelle est la morale de l'histoire? R-Indexes dans MySQL ont des performances assez médiocres jusqu'à ce qu'ils soient en mémoire, puis ils ont d'excellentes performances.Pas vraiment une bonne solution pour ce que je voulais faire avec eux, mais il offre quand même un angle intéressant sur MySQL.

Merci pour toutes les personnes d'aide.

+0

vous pourriez obtenir une réponse à http://gis.stackexchange.com – dassouki

+0

Vive l'info feront un poste là-bas et – andeyatz

+0

Pouvez-vous afficher des résultats de cette requête: EXPLAIN eXtended select count (*) from spatial_feature où MBRIntersects (GeomFromText ('LineString (7420023 1, 7420023 1)'), emplacement); Ceci montrerait comment MySQL l'exécute. Cela pourrait mettre en évidence le goulot d'étranglement. –

Répondre

0

L'objectif est de ramener tous les éléments qui coupent deux X coordonnées le long d'un seul Y coordonnez

Avez-vous envisagé d'utiliser un esprit d'index plusieurs champs? Comme:

CREATE INDEX spacial_search ON spatial_feature(y, x) 

Si vous travaillez avec un nombre limité de valeurs y c'est la voie à.

0

J'ai un diplôme en Génétique et je suis programmeur, vous n'avez pas besoin d'utiliser un X et un Y comme nomenclature ça deviendra beaucoup trop faffy ... vous avez besoin d'un début et d'un arrêt position (pas un "axe") et un chromosome nombre. Vous indexez d'abord le numéro du chromosome puis la position et ensuite vous indexez la position puis le chromosome. (Question: Traitez-vous dans les eucaryotes ou des chromosomes qui peuvent avoir deux cadres de lecture?)

EG: (où "x" = position et "y" = chromosome)

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

Soit dit en passant Chromosomes sont très longues chaînes (comme les données) que vous pouvez (pour accélérer les choses comme les blobs (codage des gènes et de l'ADN indésirable)

+0

J'essayais de simplifier un peu plus le problème pour essayer d'atteindre audience dans l'espoir que c'est quelque chose que nous bioinformaticiens se sont trompés.Il semble que le problème ne réside pas dans la création d'un index spatial qui permette ce type de recherche (j'ai appliqué la même technique dans la mémoire de programmation à un grand succès). Plus est-il possible d'utiliser les extensions spatiales de MySQL. Il semble que même s'ils peuvent surpasser n'importe quel type d'indexation pour ce type de données (binning, index linéaire ou taille maximale), l'index * doit * être en mémoire. C'est un deal breaker si vous avez 2300 DBs sur 1 serveur – andeyatz

+1

MySQL est compilé avec certains "defaults" si vous êtes courageux et vous sentez capable de descendre ce trou de lapin il y a les gars de forge.mysql .. vous pouvez compiler mysql obéir à certaines mécaniques .. c'est noyau dur mais il pourrait en valoir la peine http://forge.mysql.com/wiki/Top10SQLPerformanceTips – conners

+0

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

1

À partir du plan EXPLAIN, nous voyons que l'espace peut être utilisé pour la requête ('possible_keys' colonne), il n'est pas utilisé (NULL dans la colonne 'clé') Je ne sais pas pourquoi il n'est pas sélectionné automatiquement, mais vous pouvez explicitement ins truct MySql à utiliser l'index en spécifiant dans la requête en utilisant une clause « index de force »:

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, mon La version mysql est 5.5 – Amnon

+0

C'est la réponse à laquelle je pensais aussi. Je sais que dans les anciennes versions de MySQL, les astuces d'index ne faisaient pas toujours ce à quoi je m'attendais - je ne sais pas si cette erreur était dans l'implémentation ou mes attentes, mais il serait intéressant de voir si cela fonctionne pour l'OP. – ratsbane

0

Etes-vous sûr d'une base de données relationnelle est la voie à suivre? Si j'étais vous je regarderais en poussant vos jeux de données à Solr ou à Elastic Search (stockant probablement les ensembles de données principaux ailleurs). Ces moteurs sont construits pour l'indexation, vous remarquerez la différence dans les temps de réponse.

Questions connexes