MySQL'de Uzamsal Dizinler kullanılırken Düşük Performans


13

Bu daha iyi bir forum olacağını önerdiğinde Stack Overflow'da sorulan bir sorunun yeniden gönderilmesi.

Ben coğrafi-mekansal olmayan ama oldukça iyi uyuyor ve biraz rahatsız edici sonuçlar buluyorum bir veri kümesi itme konusunda küçük bir deney çalışıyorum. Veri seti genomik verilerdir, örneğin, genler gibi elementlerin belirli başlangıç ​​ve bitiş koordinatlarını (X eksenimiz) işgal ettiği bir DNA bölgesine sahip olduğumuz İnsan Genomudur. Y eksenini işgal eden çok sayıda DNA (kromozom) bölgesine sahibiz. Amaç, iki X koordinatını kesen tüm öğeleri tek bir Y koordinatı boyunca geri getirmek, örneğin LineString (START 1, END 2).

Teori sağlam görünüyordu, bu yüzden mevcut bir MySQL tabanlı genom projesine ittim ve şöyle bir tablo yapısı buldum:

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_idbu tabloya kodladığımız varlığın tanımlayıcısını temsil eder ve external_typebunun kaynağını kodlar. Her şey iyi görünüyordu ve iyi çalışmış gibi görünen bazı ön verileri (30.000 satır) zorladım. Bu, 3 milyon satır işaretini aştığında MySQL, uzamsal dizini kullanmayı reddetti ve kullanmak zorunda kaldığında daha yavaştı (tam tablo taraması kullanılarak 40 saniye ile 5 saniye). Daha fazla veri eklendiğinde, endeks kullanılmaya başlandı ancak performans cezası devam etti. Dizini zorlamak sorguyu 8 saniyeye indirdi. Kullandığım sorgu şöyle:

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

Buna giren veriler Y boyutları boyunca çok yoğundur (her binanın, telefon kutusunun, posta kutusunun ve güvercinlerin konumunu çok uzun bir yolda kaydettiğiniz gibi düşünün). R-Index'lerin Java'daki bu verilerle nasıl davrandığını ve alandaki diğerlerinin bunları düz dosya formatlarına başarıyla uyguladıklarını test ettim. Ancak hiç kimse bu testin amacı olan AFAIK veri tabanlarına uygulamadı.

Dışarıdaki herhangi biri, belirli bir eksen boyunca çok farklı olmayan bir uzamsal modele büyük miktarlarda veri eklerken benzer bir davranış gördü mü? Koordinat kullanımını tersine çevirirsem sorun devam eder. Bu bir nedense aşağıdaki kurulumu çalıştırıyorum

  • MacOS 10.6.6
  • MySQL 5.1.46

Yanıtlar:


5

MySQL, PostGIS gibi, uzamsal indeks verilerini bir R-ağacı yapısında saklar, böylece işleri hızlı bir şekilde bulabilir. Bir R-ağacı, bir B-ağacı gibi, tablodaki toplam verilerin sadece küçük bir kısmını almak için optimize edilecek şekilde düzenlenmiştir. Verileri döndürmek veya büyük bir birleştirme gerçekleştirmek için tablonun büyük bir bölümünü okuması gereken sorgular için dizini görmezden gelmek daha hızlıdır. tablo "yeni oluşturdukları yeni dizini kullanmıyor."

Http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/ adresinden

Tüm tablo verilerinizi belleğe sığdırabilirseniz, performansınız iyidir. Disk okumaları yapmaya başlamanız gerektiğinde / ne zaman, performans çabuk düşer. İki durum için mysql örneğinizin bellek kullanım kalıplarını mı yapıyordunuz: 30 bin satır ve 3000 bin satır?


Bunun konuya daha yakın olabileceğini düşünüyorum. TBH istediğim R-endeksi; diğer uzamsal matematik güzel bir bonus çünkü eski sistem altındaki API katmanında yapılması gerekecekti. Biraz ayar yapmayı denedim ama artan anahtar arabellekleri yardımcı olmadı (diğer arabellekler burada tablo tampon gibi yardımcı olmayacaktır çünkü onun kişisel sunucumda 1 tablo sorgusu). Garip olan, sorgular çalıştırıldığında MySQL'in makinemi yere çakması (sorgu çalışması sırasında% 100). Dedi ki tam bir masa taraması yapıyor bu yüzden belki de o kadar da garip değil
andeyatz

5

MySQL kurulumunuz veya .ini ayarlarınızla ilgili bir sorun olması gerekir. Eski mac'umda (10.6.8 / MySQL 5.2) bir coğrafi dizini test ettim. Bu yapılandırma sizinkine benzer ve büyük coğrafi veri dökümünü ( 9 milyon kayıt ) test ettim . Bu sorguyu yaptım:

SET @radius = 30;
SET @center = GeomFromText('POINT(51.51359 7.465425)');
SET @r = @radius/69.1;
SET @bbox = CONCAT('POLYGON((', 
  X(@center) - @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) - @r, ',', 
  X(@center) + @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) + @r, ',', 
  X(@center) - @r, ' ', Y(@center) - @r, '))' 
);

SELECT geonameid, SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 ))*69.1 
AS distance
FROM TABLENAME AS root
WHERE Intersects( point, GeomFromText(@bbox) ) 
AND SQRT(POW( ABS( X(point) - X(@center)), 2) + POW( ABS(Y(point) - Y(@center)), 2 )) < @r 
ORDER BY distance; 

Sadece 0.0336 saniye sürdü .

Yukarıdaki sorgu, örneğin @center için yalnızca lat / lng değerlerinin geldiği tablo city_latitude / city_longitude ve 9-12 Mio düz INDEX olduğu tablolar arasındaki karşılaştırmalar için kullanın. geonames.org sitesindeki bir coğrafi konum indeksi vardır.

Ve sadece büyük verileri bir tabloya eklediğinde, INSERT'ten sonra dizini eklemenin daha performanslı olabileceğini eklemek istedim. Değilse eklediğiniz her satır için daha uzun sürer ... [ama bu önemli değil]


Vay canına, bu gerçekten iyi. Şimdi kendi testlerimde neyi yanlış yaptığımdan emin değilim. Bir soruna neden olabilecek bir şey, daha geleneksel coğrafi veri kümelerine kıyasla veri kümelerimin doğasıdır. Bu sadece tahmin ediyorum ve bunun için bir temelim yok dedi. Hızı elde etmek için dizini belleğe zorlamanız gerekmediğini görmek harika.
andeyatz

Yarıçaplı WHERE yan tümcesi, tablonun iyi bir bölümünü bir dizin kullanarak filtreliyor olabilir.
tmarthal

2

Tek bir 2B sütun yerine iki 1D sütuna bölmeyi düşündünüz mü?

Optimize edici benzer tüm verileri boğuyor olabilir ve daha fazla çeşitlilik gösteren iki sütuna sahip olmak yardımcı olabilir.

Kontrol edebileceğiniz şey, öğelerin kontrol edilme sırasıdır. Oracle Spatial'da Soyadı ve IN_REGION filtresinde arama yaptığım bir sorun yaşadım. Oracle, en hızlı yolun soyadını kullanmak ve daha sonra bir bölge kontrolü yapmak olduğuna karar verdi. Size söyleyeyim, Cleveland'daki tüm Robinson'ları bölgeden kontrol etmek yavaş . Öncelikle uzamsal dizini kullanmaya zorlamak için Oracle'a özgü bir argümanı geçmek zorunda olduğumu hatırlıyorum.


Ne yazık ki 1 boyut, başka bir boyuttan çok daha az nüfuslu. Bunu bağlamlaştırmak için insan genomunda 24 benzersiz kromozom (22 çift ve iki cinsiyet kromozomu) ile birlikte farklı seviyelerde birleştirilmiş veri torbaları bulunur. Yani, öğeleri bir boyutta yalnızca 24 benzersiz tanımlayıcı olan temel kullanım örneğiyle eşlerseniz. Asıl umut, R-ağacı endeksinin sadece daha yüksek performanslı örtüşen aralık kontrolleri yapmakla kalmayıp aynı zamanda bu bölgeler arasında tek bir sorguda farklılaşabilmesiydi.
andeyatz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.