Mysql
 sql >> база данни >  >> RDS >> Mysql

Пространственият индекс не се използва

За съжаление ST_Distance() < threshold не е sargable критерий за търсене. За да удовлетвори тази заявка, MySQL трябва да изчисли стойността на функцията за всеки ред в таблицата и след това да я сравни с прага. Така че трябва да направи пълно сканиране на таблица (или може би пълно сканиране на индекс).

За да използвате индекс за ускоряване на тази заявка, ще ви трябва критерий за ограничаваща кутия. Заявката е много по-сложна, но и много по-бърза. Ако приемем, че вашите x/y точки във вашата геометрия представляват географска ширина/дължина в градуси, тази заявка може да изглежда така:

   set @latpoint = 38.0234332;
   set @lngpoint = -94.0724223;
   set @r = 10.0;    /* ten mile radius */
   set @units=69.0;    /* 69 statute miles per degree */
   SELECT AsText(geo) 
     FROM markers
      WHERE MbrContains(GeomFromText( 
       CONCAT('LINESTRING(', @latpoint-(@r/@units),' ',
                             @lngpoint-(@r /(@units* COS(RADIANS(@latpoint)))), 
                          ',', 
                             @latpoint+(@r/@units) ,' ', 
                             @lngpoint+(@r /(@units * COS(RADIANS(@latpoint)))),
                           ')')),
                    geo) 

Как работи това? От една страна, MbrContains( подвързан,елемент) функция е sargable . От друга страна, големият грозен елемент concat дава диагонална линия от югозападния до североизточния ъгъл на ограничаващия правоъгълник. Използвайки вашата точка от данни и радиус от десет мили, изглежда така.

LINESTRING(37.8785 -94.2564,38.1684 -93.8884)

Когато използвате GeomFromText() изобразяване на тази диагонална линия в първия аргумент на MbrContains() той служи като ограничаващ правоъгълник. MbrContains() след това може да използва изящния геометричен индекс на quadtree.

Трето, ST_Distance() , в MySQL, не обработва големи изчисления на ширина и дължина на кръга. (PostgreSQL има по-изчерпателно ГИС разширение .) MySQL е тъп като плоча в равнината. Предполага се, че вашите точки във вашите геометрични обекти са представени в равнинна геометрия. Така че ST_Distance() < 10.0 с lng/lat точки прави нещо странно.

Има един недостатък в резултатите, генерирани от тази заявка; той връща всички точки в ограничителната кутия, а не само в посочения радиус. Това е разрешимо с отделно изчисляване на разстоянието. Написах всичко това в някои подробности тук .

Забележка :За географска ширина и дължина с GPS резолюция, 32-битов FLOAT данните са с достатъчна точност. DOUBLE е това, което използва георазширението на MySQL. Когато работите в градуси, повече от пет места след десетичната запетая са извън прецизността на GPS. DECIMAL() не е идеален тип данни за координати lat/lng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изпълнение на MySQL SELECT * заявка паралелно

  2. Стойности, разделени със запетая

  3. Свързване на параметри към mysql заявка

  4. Комбинирайте резултатите за SQL заявка

  5. Вземете всички последователни блокове от списък