ประสิทธิภาพแย่เมื่อใช้ดัชนีเชิงพื้นที่ใน MySQL


13

โพสต์คำถามใหม่ที่ถามใน Stack Overflow เมื่อมีคนแนะนำว่านี่จะเป็นฟอรัมที่ดี

ฉันพยายามทดลองเล็ก ๆ น้อย ๆ ในการผลักดันชุดข้อมูลที่ไม่ใช่เชิงพื้นที่ แต่พอดีกับมันค่อนข้างดีและฉันกำลังค้นหาผลลัพธ์ที่ค่อนข้างไม่มั่นคง ชุดข้อมูลเป็นข้อมูลจีโนมเช่นจีโนมมนุษย์ที่เรามีภูมิภาคของดีเอ็นเอที่องค์ประกอบเช่นยีนครอบครองพิกัดเริ่มต้นและหยุดที่เฉพาะเจาะจง (แกน X ของเรา) เรามีหลายภูมิภาคของดีเอ็นเอ (โครโมโซม) ซึ่งครอบครองแกน Y เป้าหมายคือนำกลับรายการทั้งหมดที่ตัดกันสองพิกัด X ตามพิกัด Y เดียวเช่น LineString (เริ่ม 1, สิ้นสุด 2)

ทฤษฎีนี้ฟังดูดีดังนั้นฉันจึงผลักมันเข้าไปในโปรเจกต์จีโนมจาก 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 ปฏิเสธที่จะใช้ดัชนีเชิงพื้นที่และช้าลงเมื่อถูกบังคับให้ใช้ (40 วินาทีกับ 5 วินาทีโดยใช้การสแกนเต็มตาราง) เมื่อมีการเพิ่มข้อมูลเพิ่มเติมดัชนีจะเริ่มใช้งาน แต่การลงโทษประสิทธิภาพยังคงอยู่ การบังคับให้ดัชนีออกทำให้ข้อความค้นหาลดลงเหลือ 8 วินาที ข้อความค้นหาที่ฉันใช้ดูเหมือนว่า:

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

ข้อมูลที่จะเป็นสิ่งนี้มีความหนาแน่นสูงมากตามมิติ Y (ลองคิดดูว่าคุณได้บันทึกตำแหน่งของสิ่งปลูกสร้างทุกตู้โทรศัพท์ตู้ไปรษณีย์และนกพิราบบนถนนที่ยาวมาก) ฉันได้ทำการทดสอบว่า R-Indexes ทำงานอย่างไรกับข้อมูลนี้ใน Java เช่นเดียวกับที่คนอื่น ๆ ในเขตข้อมูลได้นำไปใช้กับรูปแบบไฟล์แบนที่ประสบความสำเร็จ อย่างไรก็ตามไม่มีใครใช้กับฐานข้อมูล AFAIK ซึ่งเป็นเป้าหมายของการทดสอบนี้

มีใครบ้างที่เห็นพฤติกรรมคล้ายกันนี้เมื่อเพิ่มข้อมูลจำนวนมากลงในโมเดลเชิงพื้นที่ซึ่งไม่แตกต่างกันมากในแกนใดแกนหนึ่ง ปัญหายังคงอยู่ถ้าฉันย้อนกลับการใช้งานพิกัด ฉันกำลังใช้งานการตั้งค่าต่อไปนี้หากเป็นสาเหตุ

  • MacOS 10.6.6
  • MySQL 5.1.46

คำตอบ:


5

MySQL เช่น PostGIS เก็บข้อมูลดัชนีเชิงพื้นที่ในโครงสร้าง R-tree เพื่อให้สามารถค้นหาสิ่งต่าง ๆ ได้อย่างรวดเร็ว R-tree เช่น B-tree ถูกจัดระเบียบในลักษณะที่มันถูกปรับให้เหมาะสำหรับการดึงข้อมูลเพียงเล็กน้อยของข้อมูลทั้งหมดในตาราง จริง ๆ แล้วมันเร็วกว่าการละเว้นดัชนีสำหรับแบบสอบถามที่ต้องการอ่านส่วนใหญ่ของตารางเพื่อส่งคืนข้อมูลหรือทำการรวมขนาดใหญ่เป็นกรณีคลาสสิกซึ่งก่อให้เกิดฟอรัมฐานข้อมูลจำนวนมาก [โปสเตอร์] บ่นเกี่ยวกับแบบสอบถามที่ส่งคืนครึ่ง ตาราง "ไม่ใช้ดัชนีใหม่ที่เพิ่งสร้างขึ้น"

จาก http://rickonrails.wordpress.com/2009/03/30/big-ole-mysql-spatial-table-optimization-tricks/

หากคุณสามารถใส่ข้อมูลตารางทั้งหมดลงในหน่วยความจำได้ประสิทธิภาพของคุณก็ดี หาก / เมื่อคุณต้องการเริ่มอ่านดิสก์ประสิทธิภาพจะไม่ดีอย่างรวดเร็ว คุณกำลังทำรูปแบบการใช้หน่วยความจำของอินสแตนซ์ mysql ของคุณสำหรับทั้งสองกรณี: แถว 30k เทียบกับแถว 3000k หรือไม่


ฉันคิดว่านี่น่าจะใกล้กับปัญหามากขึ้น TBH เป็นดัชนี R ที่ฉันต้องการ; คณิตศาสตร์เชิงพื้นที่อื่นเป็นโบนัสที่ดีเนื่องจากจะต้องทำในเลเยอร์ API ภายใต้ระบบเก่า ฉันลองปรับจูนแล้ว แต่การเพิ่มบัฟเฟอร์หลักไม่ช่วยอะไร (บัฟเฟอร์อื่น ๆ จะไม่ช่วยที่นี่เหมือนกับบัฟเฟอร์ตารางเนื่องจากคิวรี 1 ตารางของเซิร์ฟเวอร์ส่วนบุคคลของฉัน) สิ่งที่แปลกก็คือว่า MySQL ทำให้เครื่องของฉันติดดินเมื่อมีการเรียกใช้คิวรี (100% ระหว่างการรันเคียวรี) ที่กล่าวว่ามันทำการสแกนตารางเต็มดังนั้นอาจจะไม่แปลก
andeyatz

5

มีบางอย่างผิดปกติกับการติดตั้ง mysql ของคุณหรือการตั้งค่า. ini เพิ่งทดสอบดัชนีเชิงพื้นที่สำหรับ mac เครื่องเก่าของฉัน (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 วินาที

ฉันจะใช้แบบสอบถามด้านบนเช่นการเปรียบเทียบระหว่างตารางที่ตารางที่มีเพียงค่า lat / lng สำหรับ @center มาจากมี INDEX ธรรมดาจาก city_latitude / city_longitude และ 9-12 Mio ตารางจาก geonames.org มีดัชนีเชิงพื้นที่

และฉันแค่อยากจะเพิ่มว่าเมื่อใครก็ตามแทรกข้อมูลขนาดใหญ่ลงในตารางมันอาจมีประสิทธิภาพมากกว่าในการเพิ่มดัชนีหลัง INSERT ถ้าไม่ใช่มันจะใช้เวลานานขึ้นสำหรับแต่ละแถวที่คุณเพิ่ม ... [แต่นั่นไม่สำคัญ]


ว้าวมันดีจริงๆ ตอนนี้ฉันไม่แน่ใจว่าสิ่งที่ฉันทำผิดในการทดสอบของฉันเอง สิ่งหนึ่งที่อาจทำให้เกิดปัญหาคือธรรมชาติของชุดข้อมูลของฉันเมื่อเทียบกับชุดข้อมูลเชิงพื้นที่แบบดั้งเดิมมากขึ้น ที่กล่าวว่าฉันแค่คาดเดาและไม่มีพื้นฐานสำหรับเรื่องนี้ มันเยี่ยมมากที่เห็นว่าคุณไม่จำเป็นต้องบังคับให้ดัชนีเข้าสู่หน่วยความจำเพื่อให้ได้ความเร็ว
andeyatz

ส่วนคำสั่ง WHERE ที่มีรัศมีสามารถกรองส่วนที่ดีของตารางออกจากการใช้ดัชนี
tmarthal

2

คุณคิดจะแบ่งมันเป็นสองคอลัมน์ 1D แทนที่จะเป็นคอลัมน์ 2D เดียวหรือไม่?

เครื่องมือเพิ่มประสิทธิภาพสามารถสำลักข้อมูลที่คล้ายกันทั้งหมดและการมีสองคอลัมน์ที่มีความหลากหลายมากขึ้นอาจช่วยได้

สิ่งที่คุณอาจตรวจสอบคือลำดับในการตรวจสอบรายการ ฉันมีปัญหาใน Oracle Spatial เมื่อฉันค้นหานามสกุลและตัวกรอง IN_REGION Oracle ตัดสินใจว่าวิธีที่เร็วที่สุดคือใช้นามสกุลแล้วทำการตรวจสอบพื้นที่ ผมขอบอกคุณทำในการตรวจสอบในทุกภูมิภาคของโรบินสันในคลีฟแลนด์เป็นช้า ฉันจำได้ว่าฉันต้องผ่านอาร์กิวเมนต์เฉพาะของออราเคิลเพื่อบังคับให้ใช้ดัชนีเชิงพื้นที่ก่อน


น่าเสียดายที่ 1 มิติมีประชากรน้อยกว่ามิติอื่นอย่างมากมาย จีโนมมนุษย์มีโครโมโซม 24 คู่ (22 คู่และโครโมโซมเพศสองคู่) พร้อมกับถุงข้อมูลที่ประกอบกันในระดับที่แตกต่างกัน ซึ่งหมายความว่าถ้าคุณจับคู่องค์ประกอบกับกรณีการใช้งานพื้นฐานซึ่งมี 24 ตัวระบุเฉพาะในมิติเดียว ความหวังดั้งเดิมคือดัชนี R-tree จะสามารถทำการตรวจสอบช่วงที่ทับซ้อนของผู้ปฏิบัติงานได้มากกว่า แต่ยังแยกความแตกต่างระหว่างพื้นที่เหล่านี้ในแบบสอบถามเดียว
andeyatz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.