123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879 |
- package sqlite_test
- import (
- "database/sql"
- "encoding/json"
- "fmt"
- "math/rand"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "testing"
- "time"
- "github.com/spf13/cast"
- )
- func TestSQLiteBasic(t *testing.T) {
- // sqlite 内存表结构中字段类型只有 int64 float64 string, string没有长度限制
- // create table 中指定的类型没有意义,不影响数据插入
- // 实际数据类型是 由 第一次插入的数据的类型 决定的
- // 查询时,后续数据会强制转换为该类型,转不过去会报错,如将非数字字符串转换为数值
- mdb, err := sql.Open("sqlite", ":memory:")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- stmt, err := mdb.Prepare(`CREATE TABLE TEST(
- ID INT PRIMARY KEY NOT NULL,
- NAME TEXT NOT NULL,
- VALUE REAL NOT NULL,
- INTVALUE INT NOT NULL,
- DESC CHAR(1)
- )`)
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err := stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- stmt, err = mdb.Prepare("insert into test(id,name,intvalue,value,desc) values(?,?,?,?,?)")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- for i := 1; i < 10; i++ {
- id := string([]byte{})
- for n := 0; n < 16; n++ {
- id = id + string('a'+byte(n+i-1))
- }
- name := int64(30 + i)
- floatvalue := int64(12345)
- var intvalue interface{}
- intvalue = 1.2345 * float32(i)
- if i%3 == 0 {
- intvalue = "--12345--"
- } else if i%3 == 2 {
- intvalue = 123450 + i
- }
- desc := string("........................................................................................")
- rslt, err = stmt.Exec(id, name, intvalue, floatvalue, desc)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- }
- stmt, err = mdb.Prepare("select * from test")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rows, err := stmt.Query()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- defer func() { _ = rows.Close() }()
- cols, err := rows.Columns()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- colTypes, err := rows.ColumnTypes()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- types := make([]reflect.Type, len(colTypes))
- for i, tp := range colTypes {
- st := tp.ScanType()
- if st == nil {
- continue
- }
- types[i] = st
- }
- for rows.Next() {
- values := make([]interface{}, len(cols))
- for i := range values {
- values[i] = reflect.New(types[i]).Interface()
- }
- if err = rows.Scan(values...); err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- m := make(map[string]interface{})
- for i, v := range values {
- if v == nil {
- //values[i] = nil
- m[colTypes[i].Name()] = nil
- } else {
- n, ok := colTypes[i].Length()
- m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
- }
- }
- bs, _ := json.MarshalIndent(m, "", " ")
- println("values", string(bs))
- }
- }
- func TestSQLiteProfmance(t *testing.T) {
- runtime.GOMAXPROCS(1)
- println("GOMAXPROCS ", runtime.GOMAXPROCS(0))
- varfieldscount := 100
- println("Fields count ", varfieldscount+4)
- emptyfieldscount := 100
- println("Empty Fields count ", emptyfieldscount)
- vardatalength := 32
- println("VarFields data length ", vardatalength)
- datacount := 10000
- println("Data count ", datacount)
- st := time.Now()
- mdb, err := sql.Open("sqlite", ":memory:")
- // mdb, err := sql.Open("sqlite", "file::memory:?cache=shared")
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- fields := "id,name,value,desc"
- askmarks := "?,?,?,?"
- for i := 1; i <= varfieldscount; i++ {
- fields += ",var" + strconv.Itoa(i)
- askmarks += ",?"
- }
- allfields := fields
- for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
- allfields += ",var" + strconv.Itoa(i)
- }
- stmt, err := mdb.Prepare("create table if not exists test(" + allfields + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err := stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if rslt == nil {
- println("sqlite init table return nil")
- } else {
- id, err := rslt.LastInsertId()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- ra, err := rslt.RowsAffected()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if id != 0 || ra != 0 {
- println("sqlite init table return ", id, ra)
- }
- }
- println("sqlite create table use time ", time.Since(st).String())
- st = time.Now()
- stmt, err = mdb.Prepare("create index test_id_1 on test (id)")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err = stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if rslt == nil {
- println("sqlite init table index return nil")
- } else {
- id, err := rslt.LastInsertId()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- ra, err := rslt.RowsAffected()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if id != 0 || ra != 0 {
- println("sqlite init table index return ", id, ra)
- }
- }
- println("sqlite create index use time ", time.Since(st).String())
- st = time.Now()
- data := []map[string]interface{}{}
- for i := 1; i <= datacount; i++ {
- m := map[string]interface{}{}
- m["id"] = i
- m["name"] = fmt.Sprint("name", i)
- m["value"] = 1.23456789 * float64(i)
- m["desc"] = strings.Repeat(fmt.Sprint("desc", i, "."), 10)
- for vi := 1; vi <= varfieldscount; vi++ {
- bs := make([]byte, vardatalength+rand.Intn(10)-5)
- for bsi := 0; bsi < len(bs); bsi++ {
- bs[bsi] = byte(32 + rand.Intn(95))
- }
- m["var"+strconv.Itoa(vi)] = string(bs)
- }
- data = append(data, m)
- // if i%10000 == 0 {
- // println("generate maps ", i, " use time ", time.Since(st).String())
- // }
- }
- println("generate maps ", datacount, " use time ", time.Since(st).String())
- st = time.Now()
- {
- mdb.Exec("PRAGMA synchronous = OFF") // 这个跟写文件相关,内存模式没用
- mdb.Exec("begin")
- stmt, err = mdb.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- for _, d := range data {
- args := []interface{}{
- d["id"],
- d["name"],
- d["value"],
- d["desc"]}
- for vi := 1; vi <= varfieldscount; vi++ {
- args = append(args, d["var"+strconv.Itoa(vi)])
- }
- rslt, err = stmt.Exec(args...)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- // if (i+1)%10000 == 0 {
- // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
- // }
- }
- mdb.Exec("commit")
- mdb.Exec("PRAGMA synchronous = NORMAL") // 这个跟写文件相关,内存模式没用
- println("sqlite insert with transaction ", len(data), " use time ", time.Since(st).String())
- }
- st = time.Now()
- tx, err := mdb.Begin()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- stmt, err = tx.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- for _, d := range data {
- args := []interface{}{
- d["id"],
- d["name"],
- d["value"],
- d["desc"]}
- for vi := 1; vi <= varfieldscount; vi++ {
- args = append(args, d["var"+strconv.Itoa(vi)])
- }
- rslt, err = stmt.Exec(args...)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- // if (i+1)%10000 == 0 {
- // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
- // }
- }
- tx.Commit()
- println("sqlite insert with transaction ", len(data), " use time ", time.Since(st).String())
- st = time.Now()
- stmt, err = mdb.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- for _, d := range data {
- args := []interface{}{
- d["id"],
- d["name"],
- d["value"],
- d["desc"]}
- for vi := 1; vi <= varfieldscount; vi++ {
- args = append(args, d["var"+strconv.Itoa(vi)])
- }
- rslt, err = stmt.Exec(args...)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- // if (i+1)%10000 == 0 {
- // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
- // }
- }
- println("sqlite insert immediately prepare ", len(data), " use time ", time.Since(st).String())
- st = time.Now()
- for _, d := range data {
- args := []interface{}{
- d["id"],
- d["name"],
- d["value"],
- d["desc"]}
- for vi := 1; vi <= varfieldscount; vi++ {
- args = append(args, d["var"+strconv.Itoa(vi)])
- }
- sql := "insert into test(" + fields + ") values("
- for i, arg := range args {
- if i > 0 {
- sql += ","
- }
- switch a := arg.(type) {
- case string:
- sql += "'" + strings.ReplaceAll(a, "'", "''") + "'"
- default:
- sql += fmt.Sprint(arg)
- }
- }
- sql += ")"
- rslt, err = mdb.Exec(sql)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- // if (i+1)%10000 == 0 {
- // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
- // }
- }
- println("sqlite insert immediately ", len(data), " use time ", time.Since(st).String())
- st = time.Now()
- stmt, err = mdb.Prepare("select * from test")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rows, err := stmt.Query()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- println("sqlite select query all", " use time ", time.Since(st).String())
- defer func() { _ = rows.Close() }()
- cols, err := rows.Columns()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- colTypes, err := rows.ColumnTypes()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- types := make([]reflect.Type, len(colTypes))
- for i, tp := range colTypes {
- st := tp.ScanType()
- if st == nil {
- continue
- }
- types[i] = st
- }
- data = []map[string]interface{}{}
- for rows.Next() {
- values := make([]interface{}, len(cols))
- for i := range values {
- if types[i] == nil {
- values[i] = &[]byte{}
- } else {
- values[i] = reflect.New(types[i]).Interface()
- }
- }
- if err = rows.Scan(values...); err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- m := make(map[string]interface{})
- for i, v := range values {
- if v == nil {
- //values[i] = nil
- m[colTypes[i].Name()] = nil
- } else {
- n, ok := colTypes[i].Length()
- m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
- }
- }
- data = append(data, m)
- // if len(data)%10000 == 0 {
- // println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
- // }
- }
- println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
- st = time.Now()
- memdataset := map[string]map[string]interface{}{}
- for _, d := range data {
- id := cast.ToString(d["id"])
- memdataset[id] = d
- }
- println("put id-data maps ", len(memdataset), " use time ", time.Since(st).String())
- st = time.Now()
- ids := []string{}
- for id, d := range memdataset {
- if id == d["id"] {
- ids = append(ids, id)
- }
- }
- println("fetch maps data ids ", len(ids), " use time ", time.Since(st).String())
- st = time.Now()
- data = []map[string]interface{}{}
- for _, id := range ids {
- d := memdataset[id]
- data = append(data, d)
- }
- println("fetch maps data ", len(data), " use time ", time.Since(st).String())
- }
- func TestSQLiteJSON(t *testing.T) {
- // sqlite 内存表结构中字段类型只有 int64 float64 string, string没有长度限制
- // create table 中指定的类型没有意义,不影响数据插入
- // 实际数据类型是 由 第一次插入的数据的类型 决定的
- // 查询时,后续数据会强制转换为该类型,转不过去会报错,如将非数字字符串转换为数值
- mdb, err := sql.Open("sqlite", ":memory:")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- stmt, err := mdb.Prepare(`CREATE TABLE TEST(
- ID INT PRIMARY KEY NOT NULL,
- NAME TEXT NOT NULL,
- VALUE REAL NOT NULL,
- INTVALUE INT NOT NULL,
- DESC CHAR(1)
- )`)
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err := stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- stmt, err = mdb.Prepare("insert into test(id,name,intvalue,value,desc) values(?,?,?,?,?)")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- for i := 1; i < 10; i++ {
- id := string([]byte{})
- for n := 0; n < 16; n++ {
- id = id + string('a'+byte(n+i-1))
- }
- name := int64(30 + i)
- floatvalue := 12345 + (i-1)*10000
- var intvalue interface{}
- intvalue = 1.2345 * float32(i)
- if i%3 == 1 {
- intvalue = "--12345--"
- } else if i%3 == 2 {
- intvalue = 123450 + i
- }
- bs, _ := json.MarshalIndent(map[string]interface{}{
- "value": floatvalue,
- }, "", " ")
- desc := string(bs)
- rslt, err = stmt.Exec(id, name, intvalue, floatvalue, desc)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- }
- {
- stmt, err = mdb.Prepare(`select * from test`)
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rows, err := stmt.Query()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- defer func() { _ = rows.Close() }()
- cols, err := rows.Columns()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- colTypes, err := rows.ColumnTypes()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- types := make([]reflect.Type, len(colTypes))
- for i, tp := range colTypes {
- st := tp.ScanType()
- if st == nil {
- continue
- }
- types[i] = st
- }
- for rows.Next() {
- values := make([]interface{}, len(cols))
- for i := range values {
- values[i] = reflect.New(types[i]).Interface()
- }
- if err = rows.Scan(values...); err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- m := make(map[string]interface{})
- for i, v := range values {
- if v == nil {
- //values[i] = nil
- m[colTypes[i].Name()] = nil
- } else {
- n, ok := colTypes[i].Length()
- m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
- }
- }
- bs, _ := json.MarshalIndent(m, "", " ")
- println("values", string(bs))
- }
- }
- stmt, err = mdb.Prepare(`select json_group_array(json_object(
- 'id', id,
- 'name', name,
- 'value', value)) as json
- from test
- where json_extract(desc, '$.value') > 20000 and json_extract(desc, '$.value') < 50000`)
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rows, err := stmt.Query()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- defer func() { _ = rows.Close() }()
- cols, err := rows.Columns()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- colTypes, err := rows.ColumnTypes()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- types := make([]reflect.Type, len(colTypes))
- for i, tp := range colTypes {
- st := tp.ScanType()
- if st == nil {
- continue
- }
- types[i] = st
- }
- for rows.Next() {
- values := make([]interface{}, len(cols))
- for i := range values {
- values[i] = reflect.New(types[i]).Interface()
- }
- if err = rows.Scan(values...); err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- m := make(map[string]interface{})
- for i, v := range values {
- if v == nil {
- //values[i] = nil
- m[colTypes[i].Name()] = nil
- } else {
- n, ok := colTypes[i].Length()
- m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
- }
- }
- bs, _ := json.MarshalIndent(m, "", " ")
- println("values", string(bs))
- }
- }
- func TestSQLiteProfmanceMultiTable(t *testing.T) {
- runtime.GOMAXPROCS(4)
- println("GOMAXPROCS ", runtime.GOMAXPROCS(0))
- tablecount := 10000
- println("Tables count ", tablecount)
- varfieldscount := 100
- println("VarFields count ", varfieldscount+4)
- emptyfieldscount := 100
- println("EmptyFields count ", emptyfieldscount)
- vardatalength := 32
- println("VarFields data length ", vardatalength)
- tableindexcount := 100
- println("TableIndex count ", tableindexcount)
- datacount := 10000
- println("Data count ", datacount)
- mdb, err := sql.Open("sqlite", ":memory:")
- // mdb, err := sql.Open("sqlite", "file::memory:?cache=shared")
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- st := time.Now()
- for ti := 1; ti < tablecount; ti++ {
- tablename := fmt.Sprint("test", ti)
- fields := []string{"id", "name", "value", "desc"}
- varfields := strings.Join(fields, ",")
- askmarks := "?" + strings.Repeat(",?", len(fields)-1)
- for i := 1; i <= varfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- varfields += ",var" + strconv.Itoa(i)
- askmarks += ",?"
- }
- allfields := varfields
- for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- allfields += ",var" + strconv.Itoa(i)
- }
- st := time.Now()
- stmt, err := mdb.Prepare("create table if not exists " + tablename + "(" + allfields + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err := stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if rslt == nil {
- println("sqlite init table return nil")
- } else {
- id, err := rslt.LastInsertId()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- ra, err := rslt.RowsAffected()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if id != 0 || ra != 0 {
- println("sqlite init table return ", id, ra)
- }
- }
- println("sqlite create table", tablename, "use time ", time.Since(st).String())
- }
- println("sqlite create table", tablecount, "done, use time ", time.Since(st).String())
- st = time.Now()
- for ti := 1; ti < tablecount; ti++ {
- tablename := fmt.Sprint("test", ti)
- fields := []string{"id", "name", "value", "desc"}
- varfields := strings.Join(fields, ",")
- askmarks := "?" + strings.Repeat(",?", len(fields)-1)
- for i := 1; i <= varfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- varfields += ",var" + strconv.Itoa(i)
- askmarks += ",?"
- }
- allfields := varfields
- for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- allfields += ",var" + strconv.Itoa(i)
- }
- st = time.Now()
- for i, field := range fields {
- if i > tableindexcount {
- break
- }
- stmt, err := mdb.Prepare("create index " + tablename + "_" + field + " on " + tablename + " (" + field + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rslt, err := stmt.Exec()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if rslt == nil {
- println("sqlite init table index return nil")
- } else {
- id, err := rslt.LastInsertId()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- ra, err := rslt.RowsAffected()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- if id != 0 || ra != 0 {
- println("sqlite init table index return ", id, ra)
- }
- }
- }
- println("sqlite create index for table "+tablename+" use time ", time.Since(st).String())
- }
- println("sqlite create table index", tablecount, "done, use time ", time.Since(st).String())
- st = time.Now()
- data := []map[string]interface{}{}
- {
- st = time.Now()
- for i := 1; i <= datacount; i++ {
- m := map[string]interface{}{}
- m["id"] = i
- m["name"] = fmt.Sprint("name", i)
- m["value"] = 1.23456789 * float64(i)
- m["desc"] = strings.Repeat(fmt.Sprint("desc", i, "."), 10)
- for vi := 1; vi <= varfieldscount; vi++ {
- bs := make([]byte, vardatalength+rand.Intn(10)-5)
- for bsi := 0; bsi < len(bs); bsi++ {
- bs[bsi] = byte(32 + rand.Intn(95))
- }
- m["var"+strconv.Itoa(vi)] = string(bs)
- }
- data = append(data, m)
- if i%1000 == 0 {
- println("generate maps ", i, " use time ", time.Since(st).String())
- }
- }
- println("generate maps ", datacount, " use time ", time.Since(st).String())
- st = time.Now()
- memdataset := map[string]map[string]interface{}{}
- for _, d := range data {
- id := cast.ToString(d["id"])
- memdataset[id] = d
- }
- println("put id-data maps ", len(memdataset), " use time ", time.Since(st).String())
- st = time.Now()
- ids := []string{}
- for id, d := range memdataset {
- if id == cast.ToString(d["id"]) {
- ids = append(ids, id)
- }
- }
- println("fetch maps data ids ", len(ids), " use time ", time.Since(st).String())
- st = time.Now()
- data = []map[string]interface{}{}
- for _, id := range ids {
- d := memdataset[id]
- data = append(data, d)
- }
- println("fetch maps data ", len(data), " use time ", time.Since(st).String())
- }
- for ti := 1; ti < tablecount; ti++ {
- tablename := fmt.Sprint("test", ti)
- fields := []string{"id", "name", "value", "desc"}
- varfields := strings.Join(fields, ",")
- askmarks := "?" + strings.Repeat(",?", len(fields)-1)
- for i := 1; i <= varfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- varfields += ",var" + strconv.Itoa(i)
- askmarks += ",?"
- }
- allfields := varfields
- for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
- fields = append(fields, "var"+strconv.Itoa(i))
- allfields += ",var" + strconv.Itoa(i)
- }
- { // insert
- st = time.Now()
- stmt, err := mdb.Prepare("insert into " + tablename + "(" + varfields + ") values(" + askmarks + ")")
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- i := 0
- for _, d := range data {
- i = i + 1
- args := []interface{}{
- d["id"],
- d["name"],
- d["value"],
- d["desc"]}
- for vi := 1; vi <= varfieldscount; vi++ {
- args = append(args, d["var"+strconv.Itoa(vi)])
- }
- _, err := stmt.Exec(args...)
- if err != nil {
- println("err", fmt.Sprint(err))
- }
- // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
- if i%1000 == 0 {
- println("sqlite insert ", i, " use time ", time.Since(st).String())
- }
- }
- println("sqlite insert ", tablename, len(data), " use time ", time.Since(st).String())
- }
- { // select
- st = time.Now()
- stmt, err := mdb.Prepare("select " + varfields + " from " + tablename)
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- rows, err := stmt.Query()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- println("sqlite select query all", " use time ", time.Since(st).String())
- defer func() { _ = rows.Close() }()
- cols, err := rows.Columns()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- colTypes, err := rows.ColumnTypes()
- if err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- types := make([]reflect.Type, len(colTypes))
- for i, tp := range colTypes {
- st := tp.ScanType()
- if st == nil {
- continue
- }
- types[i] = st
- }
- data := []map[string]interface{}{}
- for rows.Next() {
- values := make([]interface{}, len(cols))
- for i := range values {
- if types[i] == nil {
- values[i] = &[]byte{}
- } else {
- values[i] = reflect.New(types[i]).Interface()
- }
- }
- if err = rows.Scan(values...); err != nil {
- println("err", fmt.Sprint(err))
- return
- }
- m := make(map[string]interface{})
- for i, v := range values {
- if v == nil {
- //values[i] = nil
- m[colTypes[i].Name()] = nil
- } else {
- n, ok := colTypes[i].Length()
- m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
- }
- }
- data = append(data, m)
- // if len(data)%10000 == 0 {
- // println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
- // }
- }
- println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
- }
- }
- }
|