(1)includes解決N+1查詢問題

參考資料:http://guides.ruby-china.org/active_record_querying.html#%E6%8C%89%E9%9C%80%E5%8A%A0%E8%BD%BD%E5%85%B3%E8%81%94

資料案例

N+1查詢問題

假設有如下的代碼骑疆,獲取10個客戶對象,并把客戶的郵編打印出來

clients = Client.limit(10)
 
clients.each do |client|
  puts client.address.postcode
end

商品的代碼看起來很好,但問題在于查詢的總次數(shù)。上述代碼總共會執(zhí)行1(獲取10個客戶記錄)+10(分別獲取10個客戶的地址)= 11次查詢

N+1查詢的解決辦法

我們使用includes方法可以在取出10個客戶記錄的同時把這些記錄關聯(lián)的客戶地址一次性取出來活烙,這樣我們在訪問客戶地址時就不用再去執(zhí)行查詢語句了沃斤,因為第一次已經(jīng)把所需數(shù)據(jù)全部查詢出來了。
使用includes的代碼:

clients = Client.includes(:address).limit(10)
 
clients.each do |client|
  puts client.address.postcode
end

和前面的 11 次查詢不同馋评,上述代碼只會執(zhí)行 2 次查詢:

SELECT * FROM clients LIMIT 10
SELECT addresses.* FROM addresses
WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))

構造案例

創(chuàng)建項目

rails _4.2.2_ new active_record_first -d=mysql

修改Gemfile文件诗芜,把gem源替換為source 'https://gems.ruby-china.org'瞳抓,把gem 'mysql2'替換為gem 'mysql2', '~> 0.3.18'
把database.yml文件里面的數(shù)據(jù)庫密碼設置為本地mysql數(shù)據(jù)庫的密碼

cd  active_record_first
bundle install
rake  db:create

構造數(shù)據(jù)

需要兩張表,先創(chuàng)建兩張表的遷移文件

rails g migration CreateProducts
rails g migration CreateProductSecondTags
商品表 products
image.png
image.png
商品二級標簽表 product_second_tags
image.png
image.png

我們數(shù)據(jù)表不需要默認生成的id屬性伏恐,所以添加上id: false
我們使用rails默認的數(shù)據(jù)類型孩哑,定義就用t.string、t.integer的形式翠桦。
我們需要sql語句去定義類型時横蜒,定義就用t.column后面跟上sql數(shù)據(jù)類型定義。
數(shù)據(jù)表中的外鍵經(jīng)常用于查詢销凑,所以我們一般都會加上索引丛晌。
凡是ID字段,都用CHAR(36)的類型斗幼。

添加字段
rails g migration AddSecondTagIdToProducts

我們往products表添加一個新的字段TagID澎蛛,不過我們在遷移文件里面寫的時候遷移文件名是AddSecondTagIdToProducts,而不是AddSecondTagIDToProducts

填充數(shù)據(jù)表數(shù)據(jù)
image.png
image.png
添加模型文件
image.png
image.png

product模型需要訪問它關聯(lián)的數(shù)據(jù)表記錄蜕窿,所以數(shù)據(jù)關聯(lián)belongs_to需要寫在product模型文件谋逻。而我們目前不需要通過product_second_tag.products的訪問方式呆馁,所以product_second_tag不需要添加has_many數(shù)據(jù)關聯(lián)。

添加路由文件
image.png
添加控制器文件
image.png

Rails c模型下調試

注意:在rails c模型下毁兆,無論是代碼發(fā)生變更浙滤,或者我們在navicat里面插入新的數(shù)據(jù),都需要重新進入rails c控制臺才能生效气堕。

字段大小寫

我們在find_by中根據(jù)字段進行查找時纺腊,字段不區(qū)分大小寫
我們訪問查詢結果的字段時只有id(ID)屬性不區(qū)分大小寫,其他字段區(qū)分大小寫

image.png
image.png
N+1查詢問題

每次each送巡,都執(zhí)行一次sql查詢摹菠,所以下面執(zhí)行6次each盒卸,造成6次查詢(n次查詢)


image.png

使用includes的話骗爆,在得到products記錄的時候一次性把products關聯(lián)的二級標簽記錄都得到了。不管有沒有each里面的訪問都是兩條sql查詢

image.png

視圖文件下進行調試

遺留問題蔽介,為什么會出現(xiàn)CACHE摘投,我們就算在配置文件關閉緩存,添加如下代碼config.action_controller.perform_caching = false還是會有CACHE虹蓄。

可以看到犀呼,查詢ProductSecondTag執(zhí)行多條SQL語句


image.png
image.png

使用includes之后,就算不訪問關聯(lián)表薇组,也執(zhí)行2次查詢

我們只有操作數(shù)據(jù)時才會執(zhí)行查詢語句外臂,如下不進行訪問就沒有查詢語句


image.png

image.png

我們訪問數(shù)據(jù)的長度(就算不在視圖中<%= %>進行顯示),這時就執(zhí)行了查詢語句律胀。


image.png

image.png

我們在第一個語句并不執(zhí)行sql語句宋光。后面第一次使用數(shù)據(jù)時執(zhí)行兩條sql語句獲取到所有數(shù)據(jù)了。所有第二次炭菌、第三次罪佳。。黑低。第n次使用數(shù)據(jù)時都不再執(zhí)行sql查詢語句赘艳。


image.png

image.png

image.png

使用Git做版本控制

進入項目根目錄

.../active_record_first#  git init
Initialized empty Git repository in /home/**********/active_record_first/.git/
git add -A
git commit -m "ActiveRecordFirst"

然后創(chuàng)建一個git倉庫

image.png

提交

git push -u https://github.com/xiaohuacc/active_record.git master

然后我們就可以在git倉庫看到我們提交的代碼了


image.png

在本地有時

取消提交(慎用)

我們有時從遠程倉庫拷貝代碼到本地之后,在本地提交了自己的多次修改克握,但是需求變動之后這些修改不需要了蕾管。我們可以取消這些修改,使用命令git reset --hard加上提交版本號菩暗;不過要注意我們使用該命令回退到指定A版本之后push到遠程倉庫掰曾,A版本后面的commit歷史就沒了----(無法通過commit歷史看到A版本之后的修改提交了)。一般這個命令要慎用勋眯,而且只用于回到自己最近一次本地的commit版本(該commit未push到遠程倉庫)婴梧。

我們在首次提交之后下梢,又在視圖文件添加了一下代碼。現(xiàn)在我們不要這些首次提交后的修改又很難一個個找到變動的地方改回來塞蹭,于是使用
首次提交孽江,使用git log命令查看

commit bf2bd5a242d64564cd85383e17caa1af9ce786c8
Author: ***
Date:   Sun Nov 27 14:59:05 2016 +0800
    ActiveRecordFirst

然后又做了一下修改并提交了

git add .
git commit -m "測試git取消修改功能"
[master 77f455d] 測試git取消修改功能
 2 files changed, 4 insertions(+), 4 deletions(-)

git log
commit 77f455d78967518c9db4f49812d739d3d0285224
Author: ***
Date:   Sun Nov 27 15:11:53 2016 +0800
    測試git取消修改功能

commit bf2bd5a242d64564cd85383e17caa1af9ce786c8
Author: ***
Date:   Sun Nov 27 14:59:05 2016 +0800
    ActiveRecordFirst

我們回到首次提交時的狀態(tài),去掉第二次提交的代碼修改

git reset --hard bf2bd5a242d64564cd85383e17caa1af9ce786c8
HEAD is now at bf2bd5a ActiveRecordFirst

然后回到IDE點擊YES重新加載項目代碼


image.png

然后我們git log可以看到?jīng)]有第二次提交的log番电,這也意味著我們想要回到第二次的提交也是不行了岗屏。

commit bf2bd5a242d64564cd85383e17caa1af9ce786c8
Author: ***
Date:   Sun Nov 27 14:59:05 2016 +0800
    ActiveRecordFirst

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漱办,隨后出現(xiàn)的幾起案子这刷,更是在濱河造成了極大的恐慌,老刑警劉巖娩井,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暇屋,死亡現(xiàn)場離奇詭異,居然都是意外死亡洞辣,警方通過查閱死者的電腦和手機咐刨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扬霜,“玉大人定鸟,你說我怎么就攤上這事≈浚” “怎么了联予?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長材原。 經(jīng)常有香客問我沸久,道長,這世上最難降的妖魔是什么华糖? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任麦向,我火速辦了婚禮,結果婚禮上客叉,老公的妹妹穿的比我還像新娘诵竭。我一直安慰自己,他們只是感情好兼搏,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布卵慰。 她就那樣靜靜地躺著,像睡著了一般佛呻。 火紅的嫁衣襯著肌膚如雪裳朋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天吓著,我揣著相機與錄音鲤嫡,去河邊找鬼送挑。 笑死,一個胖子當著我的面吹牛暖眼,可吹牛的內容都是我干的惕耕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诫肠,長吁一口氣:“原來是場噩夢啊……” “哼司澎!你這毒婦竟也來了?” 一聲冷哼從身側響起栋豫,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤挤安,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丧鸯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛤铜,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年骡送,在試婚紗的時候發(fā)現(xiàn)自己被綠了昂羡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡摔踱,死狀恐怖,靈堂內的尸體忽然破棺而出怨愤,到底是詐尸還是另有隱情派敷,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布撰洗,位于F島的核電站篮愉,受9級特大地震影響,放射性物質發(fā)生泄漏差导。R本人自食惡果不足惜试躏,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望设褐。 院中可真熱鬧颠蕴,春花似錦、人聲如沸助析。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽外冀。三九已至寡键,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雪隧,已是汗流浹背西轩。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工员舵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人藕畔。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓固灵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親劫流。 傳聞我的和親對象是個殘疾皇子巫玻,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內容

  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,811評論 0 11
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法祠汇,內部類的語法仍秤,繼承相關的語法,異常的語法可很,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 生活了三十多年了诗力,缺少關注自己的缺點。
    聊城水城閱讀 170評論 0 1
  • 今天早上六點起床洗漱我抠,讀經(jīng)到六點半苇本,六點半到七點吃飯,七點和海鷗一起去教會菜拓,七點半到九點在教會晨禱瓣窄,九點到九點50...
    恩寵爸爸閱讀 516評論 0 0
  • 時間--2016.6.19 父親節(jié) 我:今天記得給爺爺打電話啊,你平時都是給奶奶打電話纳鼎,不怎么給爺爺打電話 老爸:...
    子非魚a閱讀 167評論 0 0