优化count查询速度
This commit is contained in:
parent
51c8eb21a2
commit
b614642953
91
lxDb/sql.go
91
lxDb/sql.go
@ -214,6 +214,95 @@ func SqlQuery(tx *gorm.DB, sql string, list interface{}, q *PaginationQuery, par
|
|||||||
params = make([]interface{}, 0)
|
params = make([]interface{}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 条件字段
|
||||||
|
if q != nil {
|
||||||
|
where, args := q.BuildRawWhere()
|
||||||
|
if hasWhere(sql) { // 原SQL已有WHERE子句
|
||||||
|
builder.WriteString(where) // 去掉where 前头的and or ..
|
||||||
|
} else { // 原SQL没有WHERE子句
|
||||||
|
if strings.HasPrefix(where, " AND ") {
|
||||||
|
where = strings.Replace(where, " AND ", " WHERE ", 1)
|
||||||
|
builder.WriteString(where)
|
||||||
|
} else if strings.HasPrefix(where, " OR ") {
|
||||||
|
where = strings.Replace(where, " OR ", " WHERE ", 1)
|
||||||
|
builder.WriteString(where)
|
||||||
|
} else {
|
||||||
|
builder.WriteString(where) // "" 或者 " GROUP BY ..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(args) > 0 {
|
||||||
|
params = append(params, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 半成品 sql 用于查询其他信息
|
||||||
|
var sql2 = builder.String()
|
||||||
|
|
||||||
|
// 记录条数
|
||||||
|
if needDoCount(q) {
|
||||||
|
var total int64
|
||||||
|
//tx = tx.Count(&total)
|
||||||
|
tx.Raw("SELECT COUNT(*) as total FROM ("+sql2+") aaaa", params...).Take(&total)
|
||||||
|
q.Total = int(total)
|
||||||
|
if total == 0 { // 如果查了记录条数并且是0, 就不需要查记录和汇总了
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取汇总信息 // TODO: 汇总应该放到查询列表的后面
|
||||||
|
if q.Summary != "" && len(q.SummarySql) == 0 {
|
||||||
|
q.SummarySql = fieldsToSumSql(q.Summary)
|
||||||
|
}
|
||||||
|
if len(q.Summary) != 0 {
|
||||||
|
tx = tx.Offset(-1) // 需要去除offset, 否则结果可能为空, 注意: 设置0不起作用.
|
||||||
|
var summary = make(map[string]interface{})
|
||||||
|
//tx.Order("") // FIXME: 怎么去掉order by, sum是不需要order by的, 影响性能.
|
||||||
|
//tx.Select(q.SummarySql).Take(&summary) // 不适合rawsql?
|
||||||
|
|
||||||
|
tx.Raw("SELECT "+strings.Join(q.SummarySql, ", ")+" FROM ("+sql2+") ssss", params...).Take(&summary)
|
||||||
|
|
||||||
|
// []byte 转 string. 不太合理, 应该返回int或float
|
||||||
|
for k, v := range summary {
|
||||||
|
if bs, ok := v.([]byte); ok {
|
||||||
|
summary[k] = string(bs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
q.SummaryResult = summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排序处理
|
||||||
|
if q.OrderBy != "" {
|
||||||
|
s := fmt.Sprintf(" ORDER BY %s", lxUtil.FieldToColumn(q.OrderBy)) // TODO: q.OrderBy是字符串,可能多个字段 会有问题吗
|
||||||
|
builder.WriteString(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 偏移量处理
|
||||||
|
if q.Limit > 0 {
|
||||||
|
if q.Offset > 0 {
|
||||||
|
offset := (q.Offset - 1) * q.Limit
|
||||||
|
s := fmt.Sprintf(" LIMIT %d, %d", offset, q.Limit)
|
||||||
|
builder.WriteString(s)
|
||||||
|
} else {
|
||||||
|
s := fmt.Sprintf(" LIMIT %d", q.Limit)
|
||||||
|
builder.WriteString(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//tx.Raw(builder.String(), params...).Scan(list) // FIXME: unsupported data type: &[] why?
|
||||||
|
tx.Raw(builder.String(), params...).Find(list) // Find与Scan区别: list传入[]时, 查询为空的情况下, Find返回的是[], 而Scan返回的是nil.
|
||||||
|
// ref: What is the difference between Find and Scan: https://github.com/go-gorm/gorm/issues/4218
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SqlQueryNew(tx *gorm.DB, sql string, list interface{}, q *PaginationQuery, params ...interface{}) (err error) {
|
||||||
|
var builder strings.Builder
|
||||||
|
builder.WriteString(sql)
|
||||||
|
|
||||||
|
if params == nil {
|
||||||
|
params = make([]interface{}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// 条件字段
|
// 条件字段
|
||||||
if q != nil {
|
if q != nil {
|
||||||
where, args := q.BuildRawWhere()
|
where, args := q.BuildRawWhere()
|
||||||
@ -417,7 +506,7 @@ func replaceSelectAndRemoveGroupBy(sql string) string {
|
|||||||
replacedSQL := sql[:selectIndex+6] + " " + newSelectClause + " " + sql[fromIndex:]
|
replacedSQL := sql[:selectIndex+6] + " " + newSelectClause + " " + sql[fromIndex:]
|
||||||
|
|
||||||
// 去掉 GROUP BY 子句
|
// 去掉 GROUP BY 子句
|
||||||
groupByIndex := strings.Index(strings.ToUpper(replacedSQL), "GROUP BY")
|
groupByIndex := strings.LastIndex(strings.ToUpper(replacedSQL), "GROUP BY")
|
||||||
if groupByIndex != -1 {
|
if groupByIndex != -1 {
|
||||||
c := replacedSQL[groupByIndex+8:]
|
c := replacedSQL[groupByIndex+8:]
|
||||||
c = strings.TrimSpace(c)
|
c = strings.TrimSpace(c)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user