Go-SQL-Driver로 인해 maria-db CPU 사용률이 매우 높음
웹사이트와 앱의 백엔드를 위해 파이썬 플라스크에 작성한 API가 있었는데 잘 작동합니다.최근에 바둑을 배워서 전체 API를 바둑으로 다시 썼습니다.Go 바이너리 파일에서 CPU와 메모리 활용률이 훨씬 낮아질 것으로 예상했지만 MariaDB는 이제 거의 99%의 활용률을 기록했습니다.
나는 GitHub 페이지에서 max connection, max timeout, maxidle time, max... 등의 all 옵션을 제한하려고 노력하지만 여전히 소용이 없습니다.코드의 글로벌 변수로 연결되어 있고, 저는 연기합니다.result.close()
결국은db.prepare
그리고.db.query
. 바둑이 파이썬보다 훨씬 빠르다는 것을 알고 있으므로 서버에 더 많은 요청을 하는 것이 합리적이지만 유일한 테스트 환경이므로 골랑에서 마리아DB를 처리하는 방법에 대한 제안이 있습니까?
참고: 2015년부터 작동하는 원래 사이트에는 적어도 백만 행 이상의 데이터가 있습니다. 곰을 사용하여 데이터베이스를 재생성하고 데이터를 다시 삽입할 수 있지만 순수 SQL을 사용하고 싶습니다(ORM 감사합니다).
func getfulldate(c *fiber.Ctx) error {
pid := c.FormValue("pid")
result, err := db.Prepare("select concat(p.firstName, ' ', p.middle, ' ', p.lastName, ' ', p.forthName) as fullname,gender,bID,married,barcode,comment,address,if(p2.phone is null, 0, p2.phone) as phone,rName,occupation,weight,height,cast(Birthdate as date) as Birthdate from profile p left join (select phID, pID, phone from phonefix group by pID) p2 on p.pID = p2.pID left join (select pID, weight, height from bmifix group by pID) B on p.pID = B.pID, religion r where r.rgID = p.rgID and p.pID = ? ")
defer result.Close()
if err != nil {
return c.JSON(fiber.Map{"access_token": "wrong"})
}
rows, err := result.Query(pid)
defer rows.Close()
if err != nil {
return c.JSON(fiber.Map{"access_token": "wrong"})
}
columns, err := rows.Columns()
if err != nil {
return err
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
currentTime := time.Now().Format("2006-01-02")
result, err = db.Prepare("select viID,state as done,dob from visitfix where patientID = ?")
defer result.Close()
if err != nil {
return c.JSON(fiber.Map{"access_token": "wrong"})
}
rows, err = result.Query(pid)
defer rows.Close()
if err != nil {
return c.JSON(fiber.Map{"access_token": "wrong"})
}
columns = []string{"viID", "done", "dob"}
count = len(columns)
tableDatas := make([]map[string]interface{}, 0)
values = make([]interface{}, count)
valuePtrs = make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
if i == 2 {
var state string
format := "2006-1-2"
datea, err := time.Parse(format, string(b))
if err != nil {
return err
}
mydate := datea.Format("2006-01-02")
if mydate == currentTime {
state = "today"
}
if mydate < currentTime {
state = "older"
}
if mydate > currentTime {
state = "newer"
}
entry["state"] = state
}
entry[col] = v
}
tableDatas = append(tableDatas, entry)
}
alldata := [][]map[string]interface{}{tableData, tableDatas}
dat, err := json.Marshal(alldata)
if err != nil {
return err
}
return c.SendString(string(dat))
}
행 데이터를 검색하기 위한 더 나은 드라이버 구현을 금지하는 다른 언어(MySQL의 커서 구현이 중단되었을 수도 있음)와 마찬가지로 이동 프로세스 자체가 데이터베이스에 다른 영향을 미치지 않아야 합니다.
커서 사용에 관해서는 다음과 같습니다.이렇게 하면 부하가 더 오래 걸릴 수 있지만 드라이버 구현과 언어 간의 차이를 파악하려면 상당한 양의 데이터가 필요합니다.컴파일된 언어들은 그 시점에서 DB에 더 높은 부하를 가할 수 있을 것입니다.하지만 다시 한 번:이런 경우는 드물 것입니다.
여기서 살펴볼 주요 후보는 색인일 가능성이 높습니다.쿼리 중:
result, err := db.Prepare(`select concat(p.firstName, ' ', p.middle, ' ', p.lastName, ' ', p.forthName)
as fullname,gender,bID,married,barcode,comment,address,if(p2.phone is null, 0, p2.phone)
as phone,rName,occupation,weight,height,cast(Birthdate as date) as Birthdate
from profile p
left join (select phID, pID, phone from phonefix group by pID) p2 on p.pID = p2.pID
left join (select pID, weight, height from bmifix group by pID) B on p.pID = B.pID, religion r
where r.rgID = p.rgID and p.pID = ? `)
p.p.에 인덱스를 사용하길 원하십니까?ID, r.rgID 그리고 p.rgID.그러면 왼쪽 조인의 pID별 그룹도 최적이 아닌 방법으로 실행될 수 있습니다(설명을 실행하고 실행 계획을 확인합니다.
다음 문장을 통해 그룹을 제거하는 것도 개선할 수 있습니다.함수별 그룹이 없으므로 왼쪽에 있는 그룹은 사용할 수 없습니다.
result, err := db.Prepare(`select concat(p.firstName, ' ', p.middle, ' ', p.lastName, ' ', p.forthName)
as fullname,gender,bID,married,barcode,comment,address,if(p2.phone is null, 0, p2.phone)
as phone,rName,occupation,weight,height,cast(Birthdate as date) as Birthdate
from profile p
left join (select phID, pID, phone from phonefix) p2 on p.pID = p2.pID
left join (select pID, weight, height from bmifix) B on p.pID = B.pID
left join religion r
where r.rgID = p.rgID and p.pID = ? `)
항상 단일 pID를 검색하는 것이 고유한 레코드로 보이므로 다음이 더 나을 수 있습니다(테스트할 수 없음).DB 없음 :): 가능한 경우 내부 조인으로 이동합니다.그것은 왼쪽 조인보다 성능이 뛰어날 것입니다.
언급URL : https://stackoverflow.com/questions/73101963/go-sql-driver-causing-maria-db-cpu-utilization-very-high
'source' 카테고리의 다른 글
AngularJS에서 파일을 읽는 방법? (0) | 2023.09.21 |
---|---|
Flask @app.ro ute에서 python 콘솔로 인쇄하는 방법 (0) | 2023.09.21 |
안드로이드:인텐트(intent)를 사용하여 일반 텍스트 공유(모든 메시징 앱에) (0) | 2023.09.21 |
mysql의 기본 포트를 3306에서 3360으로 변경하는 방법 (0) | 2023.09.16 |
PL/SQL을 사용하여 Excel 파일(.xlsx) 만들기 (0) | 2023.09.16 |