读书人

Rails sql延迟加载跟自带缓存

发布时间: 2012-12-28 10:29:04 作者: rapoo

Rails sql延迟加载和自带缓存

color_lot_manuallies = color_lot.color_lot_manualliesif color_lot_manuallies.size == 1end

color_lot_manuallies = color_lot.color_lot_manuallies if color_lot_manuallies.size == 1 end color_lot.color_lot_manuallies.each do |i| puts i.id end
color_lot_manuallies = color_lot.color_lot_manuallies.all if color_lot_manuallies.size == 1 end color_lot.color_lot_manuallies.each do |i| puts i.id end
#PurchaseOrder has_one :purchase_order_marketing, :dependent => :destroy has_many :purchase_invoices, :dependent => :destroy,:through => :purchase_order_marketing#PurchaseOrderMarketing has_many :purchase_invoices,:dependent => :destroyPurchaseOrder.first.purchase_invoices.all(:select => 'purchase_invoices.id')
#articledef sizes sizes = [] art = self sf = art.article_secondary_feature size_group = SizeGroup.find_by_id(sf.size_groupid) if sf sizes = size_group.sizes if size_group return sizes end
ArticleMarketing.first.article.sizes.all(:select => 'id')

params[:root].classify.constantize.find_by_id(params[:id])params[:root].classify.constantize.find(params[:id])
color_lot_manuallies = color_lot.color_lot_manuallies.all ColorLotManually.find_all_by_color_lot_id(color_lot.id)
rails自带的缓存也不会用上。
关于||=缓存,参考
http://fuliang.iteye.com/blog/827321
http://www.iteye.com/topic/810957
但是有一点,||=不会自动清除或者更新,所以使用的时候还是要注意点,可能会引起取值错误,而且不会报错。
class PortOfDischage < ActiveRecord::Base  def _name    @_name ||= self.city  endend


Reloading...=> true>> p=PortOfDischage.first  SQL (0.2ms)   SET SQL_AUTO_IS_NULL=0  PortOfDischage Load (21.2ms)   SELECT * FROM `port_of_dischages` LIMIT 1  PortOfDischage Columns (1.7ms)   SHOW FIELDS FROM `port_of_dischages`+----+------------+-----------------+---------+---------+--------------------------------+--------------------------------+| id | ap_list_id | ap_marketing_id | city    | country | created_at                     | updated_at                     |+----+------------+-----------------+---------+---------+--------------------------------+--------------------------------+| 1  | 2          | 2               | Piraeus | Greece  | Thu Oct 07 07:10:21 +0800 2010 | Thu Oct 07 07:10:21 +0800 2010 |+----+------------+-----------------+---------+---------+--------------------------------+--------------------------------+1 row in set>> p._name=> "Piraeus">> p.update_attribute(:city,'p')  SQL (0.2ms)   BEGIN  ApMarketing Columns (43.0ms)   SHOW FIELDS FROM `ap_marketings`  ApMarketing Load (18.6ms)   SELECT * FROM `ap_marketings` WHERE (`ap_marketings`.`id` = 2)   PortOfDischage Update (45.5ms)   UPDATE `port_of_dischages` SET `updated_at` = '2010-12-30 13:08:47', `city` = 'p' WHERE `id` = 1  SQL (55.5ms)   COMMIT=> true>> p._name=> "Piraeus">> p.city=> "p">> p.reload  PortOfDischage Load (0.7ms)   SELECT * FROM `port_of_dischages` WHERE (`port_of_dischages`.`id` = 1) +----+------------+-----------------+------+---------+--------------------------------+--------------------------------+| id | ap_list_id | ap_marketing_id | city | country | created_at                     | updated_at                     |+----+------------+-----------------+------+---------+--------------------------------+--------------------------------+| 1  | 2          | 2               | p    | Greece  | Thu Oct 07 07:10:21 +0800 2010 | Thu Dec 30 13:08:47 +0800 2010 |+----+------------+-----------------+------+---------+--------------------------------+--------------------------------+1 row in set>> p._name=> "Piraeus"


这个缓存是action级别的,一个action之内的相同查询不会再去数据库取新的(如果当前action没有更新这条记录)。但弱的很,不过不需要手动设置什么,很方便的。也有一些隐藏的危险,比如:
p User.first(:order => "RAND()")p User.first(:order => "RAND()")

这样两次结果是相同的,如果开启了QueryCache。
User.uncached do p User.first(:order => "RAND()").id p User.first(:order => "RAND()").idend


这些方法都仍然返回一个Relation对象。直到调用map/each等方法才真正的进行数据库操作。
是对数据进行操作系吧。不然执行的不会那么慢,不知道你说的是3还是2+def cache_sql(sql) result = if @query_cache.has_key?(sql) ActiveSupport::Notifications.instrument("sql.active_record", :sql => sql, :name => "CACHE", :connection_id => self.object_id) @query_cache[sql] else @query_cache[sql] = yield end if Array === result result.collect { |row| row.dup } else result.duplicable? ? result.dup : result end rescue TypeError result end

所以多个limit就重新执行了一次
那个cache就是rails的cache
mysql的cache不会在rails的log里面打出来吧,
如果是mysql执行了cache,rails的日志应该就是正常的数据库查询,只是查询时间比较短
而且不应该是cache开头
那个class为什么会是array
我记得好像有个inspect方法是会self.to_a 所以就成array了

读书人网 >网络基础

热点推荐