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 ...
随机推荐
- utf-8 汉字对照表
之前从redis中取出一些数据,utf8 16进制编码,想转成字符,没有找到现成的转化工具,先用这个表直接查找对照吧. UTF8编码表大全Code code# Code (coded in UTF-8 ...
- [No00009C]Visual Studio在 解决方案资源管理器 里同步定位打开的文件
标题的意思就是在使用VS的时候,需要我们打开编辑的文件跟解决方案的资源管理器同步显示,这样方便定位到我们在修改哪个文件. 设置如下: 工具——选项——项目和解决方案——在解决方案资源管理器中跟踪活动项 ...
- TestNG 入门教程
原文出处:http://www.cnblogs.com/TankXiao/p/3888070.html 阅读目录 TestNG介绍 在Eclipse中在线安装TestNG 在Eclipse中离线安装T ...
- [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- [LeetCode] Excel Sheet Column Title 求Excel表列名称
Given a positive integer, return its corresponding column title as appear in an Excel sheet. For exa ...
- Spring + SpringMVC + Druid + MyBatis 给你一个灵活的后端解决方案
生命不息,折腾不止. 折腾能遇到很多坑,填坑我理解为成长. 两个月前自己倒腾了一套用开源框架构建的 JavaWeb 后端解决方案. Spring + SpringMVC + Druid + JPA(H ...
- 常用DOS命令
1.查询端口占用情况:netstat -aon |findstr "8080"; 查看端口进程号: 2.查看进程号信息: tasklist |findstr "999 ...
- hibernate通过注解实现实体和表的映射
参考: 表名的映射: //代表此类参与ORM映射,此注解必须要有 @Entity //代表user这个类映射了一个表user50,如果表名和类名一样,此注解可以省略 @Table(name=" ...
- c++中的lambda特性
来源: http://www.jb51.net/article/56147.htm cocos2dx3.0测试: 1.有参数a,b printf("lambda=%lf", []( ...
- java+jsp+servlet实现分页
web.xml配置: <servlet> <servlet-name>abc</servlet-name> <servlet-class>test.pa ...