J'utilise will_paginate pour paginer mes résultats de recherche geokit. Le code fonctionne, cependant, quand on regarde le journal, il fait le double de la requête Geokit lorsque vous utilisez l'appel will_paginate suivant:Will_paginate et geokit misbehavior (double requête)
@posts = Post.paginate :page => params[:page], :per_page => 1,
:origin => @search, :within => @miles, :include => :user
Ceci est l'appel initial non paginé qui fonctionne comme prévu (une seule requête):
@posts = Post.find(:all, :origin => @search, :within => @miles, :include => :user)
Ce qui suit est la sortie du journal lors de l'utilisation du premier appel will_paginate:
Processing PostsController#search (for 127.0.0.1 at 2010-06-03 22:10:29) [POST]
Parameters: {"commit"=>"Search", "action"=>"search", "authenticity_token"=>"K9Btfu6p7pz2mt+lWH0Fx0O7qj+0QY21JpfgyWT738I=", "controller"=>"posts", "location"=>"new york"}
Google geocoding. Address: new york. Result: <?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
<name>new york</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status>
<Placemark id="p1">
<address>New York, NY, USA</address>
<AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>NY</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>New York</SubAdministrativeAreaName><Locality><LocalityName>New York</LocalityName></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails>
<ExtendedData>
<LatLonBox north="40.8494506" south="40.5788125" east="-73.7498541" west="-74.2620917" />
</ExtendedData>
<Point><coordinates>-74.0059729,40.7142691,0</coordinates></Point>
</Placemark>
</Response></kml>
Post Load (0.7ms) SELECT *,
(ACOS(least(1,COS(0.710598048337988)*COS(-1.2916478932467)*COS(RADIANS(posts.lat))*COS(RADIANS(posts.lng))+
COS(0.710598048337988)*SIN(-1.2916478932467)*COS(RADIANS(posts.lat))*SIN(RADIANS(posts.lng))+
SIN(0.710598048337988)*SIN(RADIANS(posts.lat))))*3963.19)
AS distance FROM `posts` WHERE (((posts.lat>40.352844467866 AND posts.lat<41.075693732134 AND posts.lng>-74.4827993840952 AND posts.lng<-73.5291464159048)) AND (
(ACOS(least(1,COS(0.710598048337988)*COS(-1.2916478932467)*COS(RADIANS(posts.lat))*COS(RADIANS(posts.lng))+
COS(0.710598048337988)*SIN(-1.2916478932467)*COS(RADIANS(posts.lat))*SIN(RADIANS(posts.lng))+
SIN(0.710598048337988)*SIN(RADIANS(posts.lat))))*3963.19)
<= 25)) LIMIT 0, 1
Post Columns (2.4ms) SHOW FIELDS FROM `posts`
User Columns (2.2ms) SHOW FIELDS FROM `users`
User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 1)
Google geocoding. Address: new york. Result: <?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
<name>new york</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status>
<Placemark id="p1">
<address>New York, NY, USA</address>
<AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>US</CountryNameCode><CountryName>USA</CountryName><AdministrativeArea><AdministrativeAreaName>NY</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>New York</SubAdministrativeAreaName><Locality><LocalityName>New York</LocalityName></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails>
<ExtendedData>
<LatLonBox north="40.8494506" south="40.5788125" east="-73.7498541" west="-74.2620917" />
</ExtendedData>
<Point><coordinates>-74.0059729,40.7142691,0</coordinates></Point>
</Placemark>
</Response></kml>
SQL (0.4ms) SELECT count(*) AS count_all FROM `posts` WHERE (((posts.lat>40.352844467866 AND posts.lat<41.075693732134 AND posts.lng>-74.4827993840952 AND posts.lng<-73.5291464159048)) AND (
(ACOS(least(1,COS(0.710598048337988)*COS(-1.2916478932467)*COS(RADIANS(posts.lat))*COS(RADIANS(posts.lng))+
COS(0.710598048337988)*SIN(-1.2916478932467)*COS(RADIANS(posts.lat))*SIN(RADIANS(posts.lng))+
SIN(0.710598048337988)*SIN(RADIANS(posts.lat))))*3963.19)
<= 25))
Rendering template within layouts/application
Comme vous pouvez le voir le KML/XML et les requêtes SQL sont doublées. Une idée de ce qui se passe et comment je peux le réparer? Merci!
-Tony
Merci pour la clarification! Ça a du sens. Y a-t-il un moyen de mettre en cache les résultats? J'ai deux peurs avec ceci: 1. Limites d'API de Google/Yahoo et 2. Combien de temps cela prend pour produire l'appel d'API de Google + requête de SQL. Sur ma machine locale, cela prend environ 200 + ms pour terminer sur une seule requête - quand will_paginate est utilisé, il va de 300-430 + ms. Des pensées? – slythic
200ms semble beaucoup. Avez-vous des index définis sur vos colonnes lat/lng? En outre, la recherche sur les boîtes de délimitation pourrait améliorer les performances que je présume (semble plus facile). Plus de détails ici: http://geokit.rubyforge.org/readme.html, mais je suppose que vous l'auriez lu aussi. Rails met en cache automatiquement les requêtes identiques, mais ces requêtes ne le sont jamais. – nathanvda