我有这段代码:
package tradebot
import (
"log"
"net/http"
"strconv"
"github.com/Philipp15b/go-steam/tradeoffer"
"github.com/gorilla/mux"
)
func AcceptTrade(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
var tradeId tradeoffer.TradeOfferId
var sTradeId string
if _, has := vars["TradeId"]; has {
var err error
sTradeId = vars["TradeId"]
id, err := strconv.ParseUint(vars["TradeId"], 10, 64)
if err != nil {
http.Error(w, "Error accepting trade offer", 500)
}
tradeId = tradeoffer.TradeOfferId(id)
}
err := Trader.Accept(tradeId)
if err != nil {
log.Println(err.Error())
http.Error(w, "Failed to accept trade try again after", 500)
}
rows, err := Db.Query("SELECT DepositedBy, Price FROM skinbank WHERE tradeofferid=? AND accepted=?", sTradeId, 0)
if err != nil {
log.Println(err)
http.Error(w, "Your trade offer was accepted but there was an error on our side. Please open a ticket with the trade ID: "+sTradeId+" so we can address this issue. Thank you and sorry for the inconvenience", 500)
}
foundRows := false
for rows.Next() {
foundRows = true
var price float64
var depositedby string
err = rows.Scan(&depositedby, &price)
if err != nil {
log.Println(err)
http.Error(w, "Your trade offer was accepted but there was an error on our side. Please open a ticket with the trade ID: "+sTradeId+" so we can address this issue. Thank you and sorry for the inconvenience", 500)
}
if err != nil {
log.Println(err)
http.Error(w, "Your trade offer was accepted but there was an error on our side. Please open a ticket with the trade ID: "+sTradeId+" so we can address this issue. Thank you and sorry for the inconvenience", 500)
}
log.Println(depositedby, price)
_, err := Db.Query("UPDATE accounts SET credits = credits + ? WHERE steamid=?", price, depositedby)
if err != nil {
log.Println(err)
http.Error(w, "Your trade offer was accepted but there was an error on our side. Please open a ticket with the trade ID: "+sTradeId+" so we can address this issue. Thank you and sorry for the inconvenience", 500)
}
}
_, err = Db.Query("UPDATE skinbank SET accepted=? WHERE tradeofferid=?", 1, sTradeId)
if err != nil {
log.Println(err)
http.Error(w, "Your trade offer was accepted but there was an error on our side. Please open a ticket with the trade ID: "+sTradeId+" so we can address this issue. Thank you and sorry for the inconvenience", 500)
}
log.Println("Trade accepted: " + sTradeId)
if foundRows {
http.Redirect(w, r, "/profile", 303)
} else {
http.Error(w, "No trade with that id, either doesn't exist or already accepted.", 500)
}
}
这主要是对数据库的几次 MySQL 调用来更新/获取一些信息,我想知道是否有人可以告诉我我在这里做的效率低下的事情导致它需要 11 秒才能运行(大约在 for rows.Next()
调用中循环 6 个项目。
最佳答案
样本 A:
rows, err := Db.Query("SELECT DepositedBy, Price FROM skinbank
WHERE tradeofferid=? AND accepted=?", sTradeId, 0)
样本 B:(for 循环内)
_, err := Db.Query("UPDATE accounts SET credits = credits + ? WHERE steamid=?", price, depositedby)
样本 C:
_, err = Db.Query("UPDATE skinbank SET accepted=? WHERE tradeofferid=?", 1, sTradeId)
围绕这些放置分析时间语句。如果您不知道如何,请询问。如果您需要更多帮助,请显示表架构,方法是发出 show create table skinbank
和 show create table credits
。这将为索引提供一些线索。告诉我们两个表的行数。
如果您有大量行,如果没有适当的索引,您可能正在执行表扫描,而不是快速查找,以获取更新 where 子句中的行。哎呀,也在选择中。现在您不知道时间安排。
至少,在
上有索引skinbank(tradeofferid,accepted) -- a composite index, useful for Specimen A
credits(steamid) -- useful for Specimen B
对于样本C,它应该选择最左边的刚刚建议的综合指数。因此,如果您要采用复合路线,则仅在 skinbank(tradeofferid) 上建立单独的索引就有些过分了。
关于mysql - 为什么这一小段代码需要 11 秒来执行这几个数据库调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32294767/