简体   繁体   English

Rails ActiveRecord复杂连接问题 - 选择不起作用

[英]Rails ActiveRecord Problem With Complex Join - Select Does Not Work

I have two model objects: 我有两个模型对象:

  • Event 事件
  • Venue 地点

Events have Venues. 活动有场地。 Venues can have 1..* events. 场地可以举办1 ... *活动。

Venues have a location, a lat and long, which I use with the Geokit Rails plugin. 场地有一个位置,一个纬度和长度,我使用Geokit Rails插件。 Here's what these models look like in Rails: 以下是这些模型在Rails中的样子:

class Event < ActiveRecord::Base
  belongs_to :venue
  acts_as_mappable :through => :venue
end

and

class Venue < ActiveRecord::Base
  has_many :events
  acts_as_mappable  
end

Very simple! 非常简单! Now, I'd like to run a query, I'd like to find all the events within a few miles of a certain area, looking at the Geokit API, I see that I can use mappable with a :through association on Event, and should be able to call geokit finders on Event! 现在,我想运行一个查询,我想在某个区域的几英里范围内找到所有事件,查看Geokit API,我看到我可以使用mappable:通过关联事件,并且应该能够在Event上调用geokit finders! Excellent (so you can see above, I've added acts_as_mappable :through to the Event). 很好(所以你可以看到上面,我添加了acts_as_mappable:直到事件)。

Here's my ActiveRecord query: 这是我的ActiveRecord查询:

Event.find(:all, :origin => [lat, lng], :select => 'title', :within => 5, :limit => 10)

Here's the SQL generated: 这是生成的SQL:


SELECT `events`.`id` AS t0_r0, `events`.`title` AS t0_r1, `events`.`description` AS t0_r2,
 `events`.`created_at` AS t0_r3, `events`.`updated_at` AS t0_r4, `events`.`venue_id` AS 
t0_r5, `events`.`event_detail_id` AS t0_r6, `events`.`event_detail_type` AS t0_r7, 
`venues`.`id` AS t1_r0, `venues`.`name` AS t1_r1, `venues`.`lat` AS t1_r2, `venues`.`lng` 
AS t1_r3, `venues`.`created_at` AS t1_r4, `venues`.`updated_at` AS t1_r5 FROM `events` LEFT
 OUTER JOIN `venues` ON `venues`.id = `events`.venue_id WHERE 
(((venues.lat>51.4634898826039 AND venues.lat>51.5533406301823 AND venues.lng>-
0.197713629915149 AND venues.lng<-0.053351862714855)) AND 
((ACOS(least(1,COS(0.898991438708539)*COS(-0.00219095974226756)*COS(RADIANS(venues.lat))*COS(RADIANS(venues.lng))
 COS(0.898991438708539)*SIN(-
0.00219095974226756)*COS(RADIANS(venues.lat))*SIN(RADIANS(venues.lng))
 SIN(0.898991438708539)*SIN(RADIANS(venues.lat))))*6376.77271)
 <= 5)) LIMIT 10

Ouch. 哎哟。 Well, this takes quite some time to run, and it's not just the math, I think there's a significant problem here with performance, this takes 2 seconds to run on my desktop! 好吧,这需要相当长的时间才能运行,而且不仅仅是数学,我认为这里有一个重要的性能问题,这需要2秒才能在我的桌面上运行! But getting down to it, here is my complaint: 但要了解它,这是我的抱怨:

  • To try and improve performance, you can see I have tried to use a SELECT statement in my ActiveRecord find query. 要尝试提高性能,您可以看到我尝试在ActiveRecord查找查询中使用SELECT语句。 I just want to know the TITLES of these Events that match, not all the other fields. 我只是想知道匹配的这些事件的标题,而不是所有其他字段。 But the query goes through, and SELECTs everything from Event! 但查询通过,并从事件中选择所有内容! It uses strange aliases which I'm not familiar with like 't1_r1'. 它使用我不熟悉的奇怪别名,如't1_r1'。 So this clearly is a problem. 所以这显然是个问题。

Furthermore, this query, when run against the Venues alone (ie doing away with the JOIN) is executed in less than 10ms. 此外,这个查询,当单独对Venues运行时(即取消JOIN)在不到10ms的时间内执行。 So is there a way to do this Venues search first, and THEN do the join against the Events? 那么有没有办法首先进行Venues搜索,然后对事件进行联接? I think the join must be being done on the two tables as a whole, and only then the geocoding part comes in and slims the dataset down. 我认为必须在整个两个表上完成连接,然后只有地理编码部分进入并缩小数据集。

Any help in tightening up this issue would be much appreciated (this is a non-commercial project). 任何帮助收紧这个问题的人都会非常感激(这是一个非商业项目)。 I feel that the model is very simple I should be able to do this without too much fuss? 我觉得这个模型很简单我应该能够做到这一点而不用太大惊小怪?

Thanks in advance! 提前致谢!

(Edit: In an early version of this post I was stupid, Limit worked fine, my view was broken, edited to take that part out.) (编辑:在这篇文章的早期版本中,我是愚蠢的,限制工作正常,我的观点被打破,编辑以取出那部分。)

It looks like acts_as_mappable is using the eager loading functionality of Rails Active Record. 看起来acts_as_mappable正在使用Rails Active Record的急切加载功能。 Once you start eager loading any :select argument is ignored and you cannot specify particular columns from a table/model. 一旦你开始急切加载any :select参数被忽略,你不能从表/模型中指定特定的列。 In your case i think this is happening because of the :through=>:venue argument to acts_as_mappable . 在你的情况下,我认为这是因为:through=>:venue acts_as_mappable :through=>:venue acts_as_mappable:through=>:venue参数。 Can you make it work without the through argument? 如果没有通过论证,你能让它发挥作用吗? You can always poke around the source code as well to see if there are any other adjustments you can make. 您也可以随时查看源代码 ,看看是否还有其他调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM