schema.rb

ActiveRecord::Schema.define(version: 20150203032005) do

  create_table "addresses", force: true do |t|
t.integer "client_id"
t.string "street"
t.string "postcode"
t.datetime "created_at"
t.datetime "updated_at"
end create_table "clients", force: true do |t|
t.string "name"
t.string "gender"
t.datetime "created_at"
t.datetime "updated_at"
end create_table "infos", force: true do |t|
t.integer "address_id"
t.string "history"
t.datetime "created_at"
t.datetime "updated_at"
end end

client.rb

class Client < ActiveRecord::Base
has_one :address
end

address.rb

class Address < ActiveRecord::Base
belongs_to :client
has_many :infos
end

info.rb

class Address < ActiveRecord::Base
belongs_to :client
has_many :infos
end

Client.all

  Client Load (0.4ms)  SELECT "clients".* FROM "clients"
=> #<ActiveRecord::Relation [#<Client id: 1, name: "wei", gender: "1", created_at: "2015-02-03 02:12:36", updated_at: "2015-02-03 02:12:36">, #<Client id: 2, name: "yan", gender: "1", created_at: "2015-02-03 02:48:11", updated_at: "2015-02-03 02:48:11">]>

Address.all

SELECT "addresses".* FROM "addresses"
=> #<ActiveRecord::Relation [#<Address id: 1, client_id: 1, street: "huanyuan", postcode: "123456", created_at: "2015-02-03 02:13:45", updated_at: "2015-02-03 02:13:45">, #<Address id: 2, client_id: 2, street: "huayuan", postcode: "23456", created_at: "2015-02-03 02:50:12", updated_at: "2015-02-03 02:50:12">]>

Info.all

SELECT "infos".* FROM "infos"
=> #<ActiveRecord::Relation
[#<Info id: 1, address_id: 1, history: "1110", created_at: "2015-02-03 03:25:34", updated_at: "2015-02-03 03:25:34">,
#<Info id: 2, address_id: 1, history: "1111", created_at: "2015-02-03 03:26:16", updated_at: "2015-02-03 03:26:16">,
#<Info id: 3, address_id: 1, history: "1112", created_at: "2015-02-03 03:26:21", updated_at: "2015-02-03 03:26:21">,
#<Info id: 4, address_id: 2, history: "2110", created_at: "2015-02-03 03:26:32", updated_at: "2015-02-03 03:26:32">,
#<Info id: 5, address_id: 2, history: "2111", created_at: "2015-02-03 03:26:34", updated_at: "2015-02-03 03:26:34">,
#<Info id: 6, address_id: 2, history: "2112", created_at: "2015-02-03 03:26:37", updated_at: "2015-02-03 03:26:37">,
#<Info id: 7, address_id: 2, history: "2113", created_at: "2015-02-03 03:26:39", updated_at: "2015-02-03 03:26:39">]>

  

N + 1 查询的解决办法

clients = Client.limit(2)

clients.each do |client|
puts client.address.postcode
end

生成的sql语句为:

 SELECT "clients".* FROM "clients"
=> #<ActiveRecord::Relation
[#<Client id: 1, name: "wei", gender: "1", created_at: "2015-02-03 02:12:36", updated_at: "2015-02-03 02:12:36">,
#<Client id: 2, name: "yan", gender: "1", created_at: "2015-02-03 02:48:11", updated_at: "2015-02-03 02:48:11">]>

clients = Client.includes(:address).limit(2)

clients.each do |client|
puts client.address.postcode
end

生成的sql语句为:

 Client Load (0.5ms)  SELECT  "clients".* FROM "clients"  LIMIT 2
Address Load (0.4ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."client_id" IN (1, 2)
=> #<ActiveRecord::Relation [#<Client id: 1, name: "wei", gender: "1", created_at: "2015-02-03 02:12:36", updated_at: "2015-02-03 02:12:36">,
#<Client id: 2, name: "yan", gender: "1", created_at: "2015-02-03 02:48:11", updated_at: "2015-02-03 02:48:11">]>

按需加载多个关联

clients = Client.all
clients.each do |client|
puts client.address.infos.first.history
end

生成的sql语句:

Address Load (0.3ms)  SELECT  "addresses".* FROM "addresses"  WHERE "addresses"."client_id" = ? LIMIT 1  [["client_id", 1]]
Info Load (0.3ms) SELECT "infos".* FROM "infos" WHERE "infos"."address_id" = ? ORDER BY "infos"."id" ASC LIMIT 1 [["address_id", 1]]
1110
Address Load (0.1ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."client_id" = ? LIMIT 1 [["client_id", 2]]
Info Load (0.1ms) SELECT "infos".* FROM "infos" WHERE "infos"."address_id" = ? ORDER BY "infos"."id" ASC LIMIT 1 [["address_id", 2]]
2110
=> [#<Client id: 1, name: "wei", gender: "1", created_at: "2015-02-03 02:12:36", updated_at: "2015-02-03 02:12:36">, #<Client id: 2, name: "yan", gender: "1", created_at: "2015-02-03 02:48:11", updated_at: "2015-02-03 02:48:11">]

Client和Address是has_one关系, Address和info是has_many关系, 想要一次性加载资源使client可以通过address获取info, 使用下面语句:

clients = Client.includes(address: :infos)

生成的sql语句:

 Client Load (0.4ms)  SELECT "clients".* FROM "clients"
Address Load (0.5ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."client_id" IN (1, 2)
Info Load (0.3ms) SELECT "infos".* FROM "infos" WHERE "infos"."address_id" IN (1, 2)
=> #<ActiveRecord::Relation [#<Client id: 1, name: "wei", gender: "1", created_at: "2015-02-03 02:12:36", updated_at: "2015-02-03 02:12:36">, #<Client id: 2, name: "yan", gender: "1", created_at: "2015-02-03 02:48:11", updated_at: "2015-02-03 02:48:11">]>

  

clients.each do |c|
puts c.address.infos.first.history
end

输出:

1110
2110

rails数据库查询 N + 1 查询的解决办法的更多相关文章

  1. mysql数据库死锁的产生原因及解决办法

    这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下   数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...

  2. access数据库select查询top时无效的解决办法

    access数据库select查询top时有时无效,原因就是在使用Order by时,且排序的条件中数据有重复的. 比如:select top 10 * from table1 order by cd ...

  3. hive命令查询数据不显示表头解决办法

    在hive命令行中查询数据如下: 表头未显示出来 解决办法: 修改hive安装包conf/hive-site.xml配置文件: <property> <name>hive.cl ...

  4. SQL SERVER 数据库被标记为“可疑”的解决办法

    问题背景: 日常对Sql Server 2005关系数据库进行操作时,有时对数据库(如:Sharepoint网站配置数据库名Sharepoint_Config)进行些不正常操作如数据库在读写时而无故停 ...

  5. python 数据库操作产生中文乱码的解决办法

    1.执行python mysql数据库查询操作时,产生中文乱码 #!/usr/bin/python # -*- coding: UTF-8 -*- import MySQLdb db = MySQLd ...

  6. L SERVER 数据库被标记为“可疑”的解决办法

    问题背景: 日常对Sql Server 2005关系数据库进行操作时,有时对数据库(如:Sharepoint网站配置数据库名Sharepoint_Config)进行些不正常操作如数据库在读写时而无故停 ...

  7. SQLite数据库在多线程写锁文件的解决办法

    参考了很多SQLITE数据库多线程的解决办法 我自己写了一个SQLITEHELPER 来解决这个问题 希望大家多多指教 调用的时候  SQLLiteDBHelper _SQLLiteDBHelper ...

  8. Sql Server 2008 数据库附加失败提示9004错误解决办法

    附加数据库 对于 服务器“WSS_Content”失败.  (Microsoft.SqlServer.Smo)执行 Transact-SQL 语句或批处理时发生了异常. (Microsoft.SqlS ...

  9. sql server 数据库正在使用该文件的解决办法

    今天在帮朋友还原数据库时遇到了一个问题.朋友用的是sql server 2008数据库,本身有一个数据库,他在修改程序的时候,想修改数据库的内容.但是又不想在原数据库中修改.想备份还原出一个数据库然后 ...

  10. 远程连接mysql数据库提示:ERROR 1130的解决办法

    From: http://blog.sina.com.cn/s/blog_716844910100welz.html 在linux下使用mysql客户端连接远程mysql服务器报错: [root@Se ...

随机推荐

  1. utf-8 汉字对照表

    之前从redis中取出一些数据,utf8 16进制编码,想转成字符,没有找到现成的转化工具,先用这个表直接查找对照吧. UTF8编码表大全Code code# Code (coded in UTF-8 ...

  2. [No00009C]Visual Studio在 解决方案资源管理器 里同步定位打开的文件

    标题的意思就是在使用VS的时候,需要我们打开编辑的文件跟解决方案的资源管理器同步显示,这样方便定位到我们在修改哪个文件. 设置如下: 工具——选项——项目和解决方案——在解决方案资源管理器中跟踪活动项 ...

  3. TestNG 入门教程

    原文出处:http://www.cnblogs.com/TankXiao/p/3888070.html 阅读目录 TestNG介绍 在Eclipse中在线安装TestNG 在Eclipse中离线安装T ...

  4. [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  5. [LeetCode] Excel Sheet Column Title 求Excel表列名称

    Given a positive integer, return its corresponding column title as appear in an Excel sheet. For exa ...

  6. Spring + SpringMVC + Druid + MyBatis 给你一个灵活的后端解决方案

    生命不息,折腾不止. 折腾能遇到很多坑,填坑我理解为成长. 两个月前自己倒腾了一套用开源框架构建的 JavaWeb 后端解决方案. Spring + SpringMVC + Druid + JPA(H ...

  7. 常用DOS命令

    1.查询端口占用情况:netstat -aon |findstr "8080"; 查看端口进程号: 2.查看进程号信息:   tasklist |findstr "999 ...

  8. hibernate通过注解实现实体和表的映射

    参考: 表名的映射: //代表此类参与ORM映射,此注解必须要有 @Entity //代表user这个类映射了一个表user50,如果表名和类名一样,此注解可以省略 @Table(name=" ...

  9. c++中的lambda特性

    来源: http://www.jb51.net/article/56147.htm cocos2dx3.0测试: 1.有参数a,b printf("lambda=%lf", []( ...

  10. java+jsp+servlet实现分页

    web.xml配置: <servlet> <servlet-name>abc</servlet-name> <servlet-class>test.pa ...