rails数据库查询 N + 1 查询的解决办法
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 查询的解决办法的更多相关文章
- mysql数据库死锁的产生原因及解决办法
这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...
- access数据库select查询top时无效的解决办法
access数据库select查询top时有时无效,原因就是在使用Order by时,且排序的条件中数据有重复的. 比如:select top 10 * from table1 order by cd ...
- hive命令查询数据不显示表头解决办法
在hive命令行中查询数据如下: 表头未显示出来 解决办法: 修改hive安装包conf/hive-site.xml配置文件: <property> <name>hive.cl ...
- SQL SERVER 数据库被标记为“可疑”的解决办法
问题背景: 日常对Sql Server 2005关系数据库进行操作时,有时对数据库(如:Sharepoint网站配置数据库名Sharepoint_Config)进行些不正常操作如数据库在读写时而无故停 ...
- python 数据库操作产生中文乱码的解决办法
1.执行python mysql数据库查询操作时,产生中文乱码 #!/usr/bin/python # -*- coding: UTF-8 -*- import MySQLdb db = MySQLd ...
- L SERVER 数据库被标记为“可疑”的解决办法
问题背景: 日常对Sql Server 2005关系数据库进行操作时,有时对数据库(如:Sharepoint网站配置数据库名Sharepoint_Config)进行些不正常操作如数据库在读写时而无故停 ...
- SQLite数据库在多线程写锁文件的解决办法
参考了很多SQLITE数据库多线程的解决办法 我自己写了一个SQLITEHELPER 来解决这个问题 希望大家多多指教 调用的时候 SQLLiteDBHelper _SQLLiteDBHelper ...
- Sql Server 2008 数据库附加失败提示9004错误解决办法
附加数据库 对于 服务器“WSS_Content”失败. (Microsoft.SqlServer.Smo)执行 Transact-SQL 语句或批处理时发生了异常. (Microsoft.SqlS ...
- sql server 数据库正在使用该文件的解决办法
今天在帮朋友还原数据库时遇到了一个问题.朋友用的是sql server 2008数据库,本身有一个数据库,他在修改程序的时候,想修改数据库的内容.但是又不想在原数据库中修改.想备份还原出一个数据库然后 ...
- 远程连接mysql数据库提示:ERROR 1130的解决办法
From: http://blog.sina.com.cn/s/blog_716844910100welz.html 在linux下使用mysql客户端连接远程mysql服务器报错: [root@Se ...
随机推荐
- TCP协议学习
一.TCP参考模型 VS OSI参考模型 二.TCP/IP分层模型的四个协议层分别完成以下的功能 第一层 网络接口层 网络接口层包括用于协作IP数据在已有网络介质上传输的协议.实际上TCP/IP标准 ...
- JS 阶段练习~ 仿flash的图片轮换效果
结合了所学的简单运动框架~ 做这样一个综合小实例~~ -------------------------主要问题: 1.getByClassName IE低版的兼容性 2.DOM不够严谨 … 各种 ...
- PAT 1049. 数列的片段和(20)
给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1 ...
- 配置VSCode右键菜单
修改注册表,添加鼠标右键 选择文件 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\VSCode]@="Ope ...
- [LeetCode] Nim Game 尼姆游戏
You are playing the following Nim Game with your friend: There is a heap of stones on the table, eac ...
- [LeetCode] Set Matrix Zeroes 矩阵赋零
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click ...
- 常用Linux命令
1.mkdir 建立目录 $ mkdir testdir 2.ls 列出目录下的内容的详细信息 ls -al testdir 3.cd 更换当前工作目录 cd testdir 4.pwd ...
- Winscp开源的SSH|SFTP
WinSCP 主要功能 图形用户界面 多语言与 Windows 完美集成(拖拽, URL, 快捷方式) 支持所有常用文件操作,支持基于 SSH-1.SSH-2 的 SFTP 和 SCP 协议 支持批处 ...
- SSM整合(三):Spring4与Mybatis3与SpringMVC整合
源码下载 SSMDemo 上一节整合了Mybatis3与Spring4,接下来整合SpringMVC! 说明:整合SpringMVC必须是在web项目中,所以前期,新建的就是web项目! 本节全部采用 ...
- 配置generatorConfig.xml自动生成的代码的sql书写问题
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguratio ...