MySQL में स्थानिक सूचकांक का उपयोग करते समय खराब प्रदर्शन


13

स्टैक ओवरफ्लो पर पूछे गए एक प्रश्न का पुन: पोस्ट जब यह सुझाव दिया गया कि यह एक बेहतर मंच होगा।

मैं एक डेटा सेट पर थोड़ा प्रयोग करने की कोशिश कर रहा हूं, जो भू-स्थानिक नहीं है, लेकिन इसे काफी अच्छी तरह से फिट करता है और परिणाम कुछ हद तक परेशान कर रहा है। डेटा सेट जीनोमिक डेटा है जैसे कि मानव जीनोम जहां हमारे पास डीएनए का एक क्षेत्र है जहां जीन जैसे तत्व विशिष्ट शुरुआत (हमारे एक्स अक्ष) को रोकते हैं। हमारे पास डीएनए (गुणसूत्र) के कई क्षेत्र हैं जो वाई अक्ष पर कब्जा करते हैं। लक्ष्य उन सभी वस्तुओं को वापस लाना है जो एक एकल Y समन्वय के साथ दो X निर्देशांक को पार करते हैं जैसे कि LineString (START 1, END 1)।

सिद्धांत ध्वनि लग रहा था इसलिए मैंने इसे एक मौजूदा MySQL आधारित जीनोम परियोजना में धकेल दिया और एक तालिका संरचना के साथ आया जैसे:

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उस इकाई की पहचानकर्ता का प्रतिनिधित्व करता है जिसे हमने इस तालिका में एन्कोड किया है और इस external_typeके स्रोत को एनकोड करता है। सबकुछ अच्छा लग रहा था और मैंने कुछ प्रारंभिक आंकड़ों (30,000 पंक्तियों) में धकेल दिया, जो अच्छी तरह से काम कर रहे थे। जब यह 3 मिलियन पंक्ति के निशान से बढ़ गया था तो MySQL ने स्थानिक सूचकांक का उपयोग करने से इनकार कर दिया था और जब इसे उपयोग करने के लिए मजबूर किया गया था तो धीमी थी (पूर्ण तालिका स्कैन का उपयोग करके 5 सेकंड बनाम 5 सेकंड)। जब अधिक डेटा जोड़ा गया तो इंडेक्स का उपयोग किया जाने लगा लेकिन प्रदर्शन पेनल्टी बनी रही। इंडेक्स को बंद करने के लिए क्वेरी को 8 सेकंड तक नीचे लाया गया। मैं जिस क्वेरी का उपयोग कर रहा हूं वह इस प्रकार है:

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

इसमें जाने वाला डेटा Y आयामों के साथ बहुत घना है (इसे इस तरह समझें जैसे आपने हर इमारत की स्थिति, टेलीफोन बॉक्स, पोस्ट बॉक्स और कबूतर को बहुत लंबी सड़क पर दर्ज किया है)। मैंने परीक्षण किया है कि आर-इंडेक्स जावा में इस डेटा के साथ कैसे व्यवहार करता है और साथ ही साथ क्षेत्र के अन्य लोगों ने उन्हें सफलता के लिए फ्लैट-फाइल स्वरूपों में लागू किया है। हालाँकि किसी ने उन्हें डेटाबेस AFAIK पर लागू नहीं किया है जो इस परीक्षण का लक्ष्य है।

क्या वहाँ किसी ने एक समान व्यवहार देखा है जब बड़ी मात्रा में डेटा को एक स्थानिक मॉडल में जोड़ा जाता है जो एक विशेष अक्ष के साथ बहुत अलग नहीं है? यदि मैं समन्वय उपयोग को उलट देता हूं तो समस्या बनी रहती है। मैं निम्नलिखित सेटअप चला रहा हूँ अगर यह एक कारण है

  • MacOS 10.6.6
  • MySQL 5.1.46

जवाबों:


5

MySQL, PostGIS की तरह, यह R- ट्री संरचना में स्थानिक सूचकांक डेटा संग्रहीत करता है ताकि यह सामान तेजी से पा सके। बी-ट्री की तरह एक आर-ट्री को इस तरह से व्यवस्थित किया जाता है कि यह तालिका में कुल डेटा का केवल एक छोटा सा अंश प्राप्त करने के लिए अनुकूलित है। यह वास्तव में तेज़ी से प्रश्नों के सूचकांक को अनदेखा करने के लिए तेज़ है जो डेटा को वापस करने के लिए तालिका के एक बड़े हिस्से को पढ़ने या एक विशाल ज्वाइन करने की आवश्यकता है, एक क्लासिक मामला जो कई डेटाबेस फ़ोरम को जन्म देता है [पोस्टर] एक क्वेरी के बारे में शिकायत करना जो आधा उनके पास लौटता है तालिका "वे अभी बनाए गए नए सूचकांक का उपयोग नहीं कर रहे हैं।"

से http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/

यदि आप अपने सभी टेबल डेटा को मेमोरी में फिट कर सकते हैं, तो आपका प्रदर्शन अच्छा है। यदि / जब आपको डिस्क रीडिंग शुरू करने की आवश्यकता होती है, तो प्रदर्शन जल्दी खराब हो जाता है। क्या आप दो मामलों के लिए अपने mysql उदाहरण के मेमोरी उपयोग पैटर्न कर रहे थे: 30k पंक्तियाँ बनाम 3000k पंक्तियाँ?


मुझे लगता है कि यह मुद्दे के करीब हो सकता है। टीबीएच इसके आर-इंडेक्स मैं चाहता हूं; अन्य स्थानिक गणित एक अच्छा बोनस है क्योंकि इसे पुराने सिस्टम के तहत एपीआई लेयर में करना होगा। मैंने थोड़ी ट्यूनिंग करने की कोशिश की, लेकिन महत्वपूर्ण बफ़र्स को बढ़ाने में मदद नहीं की (अन्य बफ़र्स टेबल बफर की तरह यहां मदद नहीं करेंगे क्योंकि यह मेरे व्यक्तिगत सर्वर पर 1 टेबल क्वेरी है)। क्या अजीब बात है कि जब प्रश्न चलता है तो MySQL मेरी मशीन को जमीन में गाड़ देता है (क्वेरी रन के दौरान 100%)। यह कहा कि इसकी एक पूर्ण तालिका स्कैन कर रही है तो शायद यह अजीब नहीं है
andeatz

5

आपके mysql स्थापना या .ini सेटिंग्स के साथ कुछ गलत होना चाहिए। बस मेरे पुराने मैक (10.6.8 / MySQL 5.2) पर एक भू-स्थानिक सूचकांक का परीक्षण किया। यह कॉन्फ़िगरेशन आपके जैसा है और मैंने बड़े जियोडेटा डंप ( 9 मिलियन रिकॉर्ड ) का परीक्षण किया । मैंने यह प्रश्न किया:

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; 

इसमें महज 0.0336 सेकेंड लगे।

मैं उपरोक्त क्वेरी का उपयोग करता हूं उदाहरण के लिए तालिकाओं के बीच तुलना करने के लिए जहां तालिका जहां @ आईसेंटर के लिए केवल लेट / लैंग वैल्यू से आती है, उसमें एक सादा INDEX है city_latitude / city_longitude और 9-12 Mio से। geonames.org की तालिका में एक भू-स्थानिक सूचकांक है।

और मैं बस यह जोड़ना चाहता था कि जब कोई भी बड़े डेटा को एक तालिका में सम्मिलित करता है तो INSERT के बाद सूचकांक को जोड़ने के लिए अधिक प्रदर्शन करने वाला हो सकता है। यदि नहीं तो आपको जोड़ने वाली प्रत्येक पंक्ति में अधिक समय लगेगा ... [लेकिन यह महत्वपूर्ण नहीं है]


वाह, यह वास्तव में अच्छा है। अब मुझे यकीन नहीं है कि मैं अपने परीक्षणों में गलत कर रहा था। एक बात जो किसी समस्या का कारण हो सकती है, वह है अधिक पारंपरिक भू-स्थानिक डेटा सेटों की तुलना में मेरे डेटा सेटों की प्रकृति। कहा कि मैं सिर्फ अनुमान लगा रहा हूं और इसका कोई आधार नहीं है। यह देखना शानदार है कि आपको गति प्राप्त करने के लिए इंडेक्स को मेमोरी में बाध्य करने की आवश्यकता नहीं है।
एंडजेट

जहां त्रिज्या के साथ खंड एक सूचकांक का उपयोग करने से तालिका के एक अच्छे हिस्से को छान सकता है।
tmarthal

2

क्या आपने इसे एक 2 डी कॉलम के बजाय दो 1D कॉलम में तोड़ने के बारे में सोचा है?

ऑप्टिमाइज़र को सभी समान डेटा पर चोक किया जा सकता है और अधिक से अधिक विविधता वाले दो कॉलम रखने में मदद मिल सकती है।

आप जो भी देख सकते हैं वह वह क्रम है जिसमें वस्तुओं की जाँच की जाती है। मुझे Oracle स्थानिक में एक समस्या थी जहाँ मुझे अंतिम नाम और एक IN_REGION फ़िल्टर पर खोजा गया था। ओरेकल ने सबसे तेज़ तरीका तय किया कि अंतिम नाम का उपयोग करें और फिर एक क्षेत्र की जांच करें। आपको बता दें, क्लीवलैंड के सभी रॉबिन्सन पर क्षेत्र की जांच धीमी है । मुझे याद है कि पहले मुझे स्थानिक सूचकांक का उपयोग करने के लिए मजबूर करने के लिए एक ओरेकल विशिष्ट तर्क पारित करना था।


दुर्भाग्य से 1 आयाम दूसरे आयाम की तुलना में काफी कम आबादी वाला है। इस संदर्भ में विचार करने के लिए मानव जीनोम में 24 अद्वितीय गुणसूत्र (22 जोड़े और दो लिंग गुणसूत्र) के साथ-साथ डेटा का एक बैग होता है जिसे विभिन्न स्तरों पर इकट्ठा किया गया है। जिसका अर्थ है कि यदि आप मूल उपयोग के मामले में तत्वों को मैप करते हैं जो एक आयाम में केवल 24 अद्वितीय पहचानकर्ता हैं। मूल आशा यह थी कि आर-ट्री इंडेक्स न केवल अधिक प्रदर्शन करने वाले अतिव्यापी रेंज चेक करने में सक्षम होगा बल्कि इन क्षेत्रों के बीच एक ही क्वेरी में अंतर भी कर सकता है।
andeyatz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.