2016-04-25 1 views
-1

Sur une recherche géospaciale avec un index géospacial sur le champ geom, ma requête de temps augmente anormalement quand je veux ORDER BY distance, existe-t-il une syntaxe alternative ou des astuces pour éviter cela? Remarque je suis au courant de ce post: https://explainextended.com/2011/02/11/late-row-lookups-innodb/ mais cette astuce ne peut pas être réaliser avec la requête ci-dessous:LIMIT avec ORDER BY solution de requête de ralentissement pour mysql géospacial 5.7

cette requête sans commande par prendre

0,005 s
SELECT 
ST_Distance_Sphere(Point(2.34, 48.85), geom) as distance 
FROM testgeo1 
WHERE ST_Contains(ST_MakeEnvelope(
        Point((2.34+(500/111)), (48.85+(500/111))), 
        Point((2.34-(500/111)), (48.85-(500/111))) 
       ), geom) 
    LIMIT 500 

EXPLIQUEZ:

+----+-------------+----------+------------+-------+---------------+----------+---------+------+------+----------+-------------+ 
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref | rows | filtered | Extra  | 
+----+-------------+----------+------------+-------+---------------+----------+---------+------+------+----------+-------------+ 
| 1 | SIMPLE  | testgeo1 | NULL  | range | sp_index  | sp_index | 34  | NULL | 2609 | 100.00 | Using where | 
+----+-------------+----------+------------+-------+---------------+----------+---------+------+------+----------+-------------+ 

celui-ci avec ORDER BY prend 0.16s

SELECT 
    ST_Distance_Sphere(Point(2.34, 48.85), geom) as distance 
    FROM testgeo1 
    WHERE ST_Contains(ST_MakeEnvelope(
         Point((2.34+(500/111)), (48.85+(500/111))), 
         Point((2.34-(500/111)), (48.85-(500/111))) 
        ), geom) 
ORDER BY distance 
     LIMIT 500 

solutions, suggestion, syntaxe alternative ou astuces sont les bienvenus ..

+0

@Rick ur lien va localhost .. vous pouvez le fixer s'il vous plaît – jess

+0

(Désolé ...) La conception http: // mysql. rjweb.org/doc.php/latlng peut être plus rapide. –

+0

@Rick ur metheod semble intéressant, mais je garderais la nouvelle méthode standard Mysql comme je l'ai posté, de cette façon est très efficace sans ordre par, son pointage sur un bogue mysql commun, je suis à la recherche d'une syntaxe alternative simple, voir cette note: https://mariadb.com/kb/en/mariadb/improvements-to-order-by/ merci anayway – jess

Répondre

0

S'il y a plusieurs milliers de points dans cette enveloppe, ...

  • La première requête (pas ORDER BY) sera choisissez les 500 premiers qu'il trouve dans cette enveloppe.
  • La deuxième requête (avec ORDER BY) doit trouver tous les points dans l'enveloppe, calculer la distance pour chacun, trier le résultat, puis livrer 500.

Ceci est un simple fait de vie sur les LIMIT avec et sans ORDER BY. Il n'a rien de spécifique à faire avec SPATIAL ou 5.7.

S'il vous plaît fournir la preuve de ce que je réclame en faisant

SELECT COUNT(*) 
    FROM testgeo1 
    WHERE ST_Contains(ST_MakeEnvelope(
       Point((2.34+(500/111)), (48.85+(500/111))), 
       Point((2.34-(500/111)), (48.85-(500/111))) 
      ), geom) ; 
+0

le outputt est 1277, j'ai 1 million de lignes dans la table, pas sûr de voir quel est le point .. – jess

+0

Il devait calculer 'ST_Distance_Sphere' 1277 fois. Hélas, cela ne suffit pas pour faire valoir mon point de vue. S'il vous plaît poster 'EXPLAIN SELECT ...' –

+0

j'ai édité mon poste et ajouté la question d'expliquer, je me demande si c'est un "ordre commun par bogue" avec mysql, je voudrais tester la même chose sur mariadb mais je ne suis pas sûr que mysql 5.7 fonction sont encore implémentées – jess