mysql優化之N 1問題

2021-10-18 16:30:58 字數 2050 閱讀 6493

a物件關聯b物件,a物件進行列表展示時需顯示b物件的關聯屬性,這樣需要先用一條sql將n個a物件查詢出來,再用n條sql將這些物件的關聯屬性查詢出來。違背了減少資料庫互動原則,影響效能。

千萬不要在for迴圈裡面進行sql查詢操作

就像下面我當初寫的破**

trainclassvolist.

foreach

(trainclassvo -

>

}// 取證率%

numberformat numberformat = numberformat.

getinstance()

;// 設定精確到小數點後2位

numberformat.

setmaximumfractiondigits(2

);if(stucertificatenum !=

0&& trainstumun !=0)

else

// 獲取學時未完**數

long count = trainclassstulist.

stream()

.filter

(trainclassstudent -

> trainclassstudent.

getstudystatus()

.equals

("1"))

.count()

; trainclassvo.

settrainstunoendmun

(count)

;}

2.解決方法

方法一:連線查詢,在查詢a物件的時候,將關聯的b物件查詢出來。缺點:1、連線的表增加,sql效能下降;2、如果n個a物件關聯的是同乙個b物件,會使結果集非常龐大,返回結果集需要消耗效能,並且影響排序效能。比如100個employee都關聯dept id 1,本來dept的資料只需出現一次,這裡為了避免n+1,重複出現100次。

方法二:a表中設定冗餘字段。缺點:更新b表需要更新a表。更新a表時需要增加修改b物件屬性的邏輯。這個方法最好別用,有時候會存在忘記更新資料的情況。

方法三:效能最佳,1+1查詢。先用sql查出所有employee查詢出,將他們關聯的deptid放到乙個set中,再發一條sql,deptid in set 將所有dept查出,之後在程式中將deptset 進入employee。

下面是我重構的**,展示部分

list

deptidlist = trainclassvolist.

stream()

.map

(trainclassvo:

:getcreatedept)

.collect

(collectors.

tolist()

);// 培訓機構資訊列表

map> map =

newhashmap

<

>()

;if(deptidlist.

size()

>0)

);}

sql:

"getinfobydeptidlist"

parametertype

="list"

resulttype

="com.gl.train.api.entity.commorgaudit"

>

select

coa.id,coa.dept_id,coa.org_name,coa.org_unit_name

from

comm_org_audit coa

where coa.dept_id in

collection

="list"

separator

=","

open

="("

close

=")"

item

="item"

>

#foreach

>

select

>

Hibernate解決n 1問題

觀點 對於n 1問題的理解。一般而言說n 1意思是,無論在一對多還是多對一當查詢出n條資料之後,每條資料會關聯的查詢1次他的關聯物件,這就叫做n 1。但是我的理解是,本來所有資訊可以一次性查詢出來,也就是簡單的連表查詢,但是hibernate會首先查詢1次得到當前物件,然後當前物件裡面的n個關聯物件...

n 1次select查詢問題

什麼叫n 1次select查詢問題?在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列...

HIBERNATE的N 1查詢問題

在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列出了customers表和order...