Re-poster une question posée sur Stack Overflow quand il a été suggéré que ce serait un meilleur forum.
J'essaie une petite expérience pour pousser un ensemble de données qui n'est pas géospatial mais qui lui convient assez bien et je trouve les résultats quelque peu troublants. L'ensemble de données est constitué de données génomiques, par exemple 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 exemple LineString (START 1, END 2).
La théorie semblait solide, alors je l'ai poussée dans un projet de génome basé sur MySQL et j'ai trouvé 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 encodé dans ce tableau et en external_type
code la source. Tout avait l'air bien et j'ai inséré des données préliminaires (30 000 lignes) qui semblaient bien fonctionner. Lorsque cela a dépassé la barre des 3 millions de lignes, MySQL a refusé d'utiliser l'index spatial et a été plus lent lorsqu'il a été contraint de l'utiliser (40 secondes contre 5 secondes en utilisant une analyse complète de la table). Lorsque davantage de données ont été ajoutées, l'index a commencé à être utilisé, mais la dégradation des performances a persisté. Le fait de forcer l'index a ramené la requête à 8 secondes. La requête que j'utilise ressemble à:
select count(*)
from spatial_feature
where MBRIntersects(GeomFromText('LineString(7420023 1, 7420023 1)'), location);
Les données qui y entrent sont très denses le long des dimensions Y (pensez-y comme si vous aviez 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 le comportement des R-Index avec ces données en Java et d'autres sur le terrain les ont appliquées avec succès aux formats de fichiers plats. Cependant, personne ne les a appliqués aux bases de données AFAIK qui est le but de ce test.
Quelqu'un a-t-il vu un comportement similaire lors de l'ajout de grandes quantités de données à un modèle spatial qui n'est pas très disparate le long d'un axe particulier? Le problème persiste si j'inverse l'utilisation des coordonnées. J'exécute la configuration suivante si c'est une cause
- MacOS 10.6.6
- MySQL 5.1.46
Quelque chose ne va pas avec votre installation mysql ou les paramètres .ini. Je viens de tester un index géospatial sur mon ancien mac (10.6.8 / MySQL 5.2). Cette configuration est similaire à la vôtre et j'ai testé le grand vidage de géodonnées ( 9 millions d'enregistrements ). J'ai fait cette requête:
Cela n'a pris que 0,0336 sec.
J'utilise la requête ci-dessus, par exemple pour les comparaisons entre les tables où la table d'où viennent les valeurs lat / lng pour @center a un INDEX simple de city_latitude / city_longitude et le 9-12 Mio. table de geonames.org a un index géospatial.
Et je voulais juste ajouter que lorsque quelqu'un insère les données volumineuses dans une table, il pourrait être plus performant d'ajouter l'index après INSERT. Sinon, cela prendra plus de temps pour chaque ligne que vous ajoutez ... [mais ce n'est pas important]
la source
Avez-vous pensé à le diviser en deux colonnes 1D au lieu d'une seule colonne 2D?
L'optimiseur pourrait étouffer toutes les données similaires et avoir deux colonnes avec une plus grande variété pourrait aider.
Vous pouvez également vérifier l'ordre dans lequel les articles sont vérifiés. J'ai eu un problème dans Oracle Spatial où je faisais une recherche sur le nom de famille et un filtre IN_REGION. Oracle a décidé que le moyen le plus rapide était d'utiliser le nom de famille, puis de vérifier la région. Permettez-moi de vous dire que faire une vérification dans la région de tous les Robinson de Cleveland est lent . Je me souviens que je devais passer un argument spécifique à Oracle pour le forcer à utiliser l'index spatial en premier.
la source