Ruby on rails Will_paginate和geokit不当行为(双重查询)

Ruby on rails Will_paginate和geokit不当行为(双重查询),ruby-on-rails,activerecord,will-paginate,geokit,Ruby On Rails,Activerecord,Will Paginate,Geokit,我正在使用will_paginate对我的geokit搜索结果进行分页。但是,当查看日志时,代码会起作用,当使用以下will_paginate调用时,它会使geokit查询加倍: @posts = Post.paginate :page => params[:page], :per_page => 1, :origin => @search, :within => @miles, :include => :user

我正在使用will_paginate对我的geokit搜索结果进行分页。但是,当查看日志时,代码会起作用,当使用以下will_paginate调用时,它会使geokit查询加倍:

@posts = Post.paginate :page => params[:page], :per_page => 1, 
                        :origin => @search, :within => @miles, :include => :user
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
这是按预期工作的原始未分页调用(单个查询):

以下是使用第一个will_paginate调用时的日志输出:

@posts = Post.paginate :page => params[:page], :per_page => 1, 
                        :origin => @search, :within => @miles, :include => :user
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
如您所见,KML/XML和SQL查询增加了一倍。你知道发生了什么事,我该怎么解决吗?谢谢


-托尼实际上这是标准行为。will_paginate首先统计记录数,然后检索20行,具体取决于可见页面和页面上的行数 (因此查询并不完全相同)

显示页数时需要计数


但是您的日志记录对我来说并不完全有意义,因为will_paginate查询会将数字限制为20(或任何页面大小),而且显示的查询也不完全相同:例如,我看到了不同的条件。

感谢您的澄清!这是有道理的。有没有办法缓存结果?我对此有两种担心:1。谷歌/雅虎API限制和2。生成GoogleAPI调用+SQL查询需要多长时间。在我的本地机器上,一个查询大约需要200+毫秒才能完成-何时使用will_paginate,它的时间从300-430+毫秒。有什么想法吗?200毫秒似乎很多。是否在lat/lng列上定义了索引?此外,我认为搜索边界框可以提高性能(似乎更容易)。这里有更多的细节:,但我想你也会读到的。Rails会自动缓存相同的查询,但这样的查询永远不会被缓存。