我有一个API,我写在python flask 的网站和应用程序的后端,它的工作很好。我最近学习了围棋,并重写了整个API在围棋。我期望更低的CPU和内存利用率从围棋二进制文件,但MariaDB现在几乎99%的利用率。
我尝试限制最大连接,最大超时,最大空闲时间,最大...等所有选项在GitHub页面仍然没有使用。我有连接作为全局变量在代码中,我在每个db.prepare
和db.query
之后延迟result.close()
。我知道Go语言比Python快得多,所以向服务器发出更多请求是有意义的,但它是唯一的测试环境,它应该会导致那么多的CPU利用率关于如何在Golang处理MariaDB建议?
FYI:原来的网站从2015年开始工作,它至少有超过百万行的数据,我可以使用gorm重新创建数据库,并再次插入数据,但我真的只想使用纯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))
}
1条答案
按热度按时间vktxenjb1#
go进程本身不应该像任何其他语言一样对(任何)数据库产生任何其他影响,除非有更好的驱动程序实现来检索行数据(MySQL的游标实现曾经(可能仍然)被破坏)。
至于游标的用法:这可以将负载分散到更长的时间,但您需要大量的数据来注意驱动程序实现和语言之间的差异。编译语言将能够在该时间点上对数据库施加更高的负载。但再次强调:这种情况很少见。
这里要查看的主要候选对象很可能是索引:您正在查询:
您希望在p.pID、r.rgID和p.rgID上有索引。那么,左连接中pID上的group by可能也会以次优方式执行(运行一个explain并检查执行计划)。
一种改进方法是删除group by语句:您没有group by函数,因此在左连接中没有group by的用处:
由于您总是检索单个pID,并且该pID似乎是唯一的记录,因此以下方法可能更好(无法测试:没有您的DB:)):如果可能,请转到内部联接:它的性能应该优于左连接