sqlite_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. package sqlite_test
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "fmt"
  6. "math/rand"
  7. "reflect"
  8. "runtime"
  9. "strconv"
  10. "strings"
  11. "testing"
  12. "time"
  13. "gitee.com/wecisecode/util/cast"
  14. )
  15. func TestSQLiteBasic(t *testing.T) {
  16. // sqlite 内存表结构中字段类型只有 int64 float64 string, string没有长度限制
  17. // create table 中指定的类型没有意义,不影响数据插入
  18. // 实际数据类型是 由 第一次插入的数据的类型 决定的
  19. // 查询时,后续数据会强制转换为该类型,转不过去会报错,如将非数字字符串转换为数值
  20. mdb, err := sql.Open("sqlite", ":memory:")
  21. if err != nil {
  22. println("err", fmt.Sprint(err))
  23. return
  24. }
  25. stmt, err := mdb.Prepare(`CREATE TABLE TEST(
  26. ID INT PRIMARY KEY NOT NULL,
  27. NAME TEXT NOT NULL,
  28. VALUE REAL NOT NULL,
  29. INTVALUE INT NOT NULL,
  30. DESC CHAR(1)
  31. )`)
  32. if err != nil {
  33. println("err", fmt.Sprint(err))
  34. return
  35. }
  36. rslt, err := stmt.Exec()
  37. if err != nil {
  38. println("err", fmt.Sprint(err))
  39. return
  40. }
  41. println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  42. stmt, err = mdb.Prepare("insert into test(id,name,intvalue,value,desc) values(?,?,?,?,?)")
  43. if err != nil {
  44. println("err", fmt.Sprint(err))
  45. return
  46. }
  47. for i := 1; i < 10; i++ {
  48. id := string([]byte{})
  49. for n := 0; n < 16; n++ {
  50. id = id + string('a'+byte(n+i-1))
  51. }
  52. name := int64(30 + i)
  53. floatvalue := int64(12345)
  54. var intvalue interface{}
  55. intvalue = 1.2345 * float32(i)
  56. if i%3 == 0 {
  57. intvalue = "--12345--"
  58. } else if i%3 == 2 {
  59. intvalue = 123450 + i
  60. }
  61. desc := string("........................................................................................")
  62. rslt, err = stmt.Exec(id, name, intvalue, floatvalue, desc)
  63. if err != nil {
  64. println("err", fmt.Sprint(err))
  65. }
  66. println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  67. }
  68. stmt, err = mdb.Prepare("select * from test")
  69. if err != nil {
  70. println("err", fmt.Sprint(err))
  71. return
  72. }
  73. rows, err := stmt.Query()
  74. if err != nil {
  75. println("err", fmt.Sprint(err))
  76. return
  77. }
  78. defer func() { _ = rows.Close() }()
  79. cols, err := rows.Columns()
  80. if err != nil {
  81. println("err", fmt.Sprint(err))
  82. return
  83. }
  84. colTypes, err := rows.ColumnTypes()
  85. if err != nil {
  86. println("err", fmt.Sprint(err))
  87. return
  88. }
  89. types := make([]reflect.Type, len(colTypes))
  90. for i, tp := range colTypes {
  91. st := tp.ScanType()
  92. if st == nil {
  93. continue
  94. }
  95. types[i] = st
  96. }
  97. for rows.Next() {
  98. values := make([]interface{}, len(cols))
  99. for i := range values {
  100. values[i] = reflect.New(types[i]).Interface()
  101. }
  102. if err = rows.Scan(values...); err != nil {
  103. println("err", fmt.Sprint(err))
  104. return
  105. }
  106. m := make(map[string]interface{})
  107. for i, v := range values {
  108. if v == nil {
  109. //values[i] = nil
  110. m[colTypes[i].Name()] = nil
  111. } else {
  112. n, ok := colTypes[i].Length()
  113. m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
  114. }
  115. }
  116. bs, _ := json.MarshalIndent(m, "", " ")
  117. println("values", string(bs))
  118. }
  119. }
  120. // GOMAXPROCS 1
  121. // Fields count 104
  122. // Empty Fields count 100
  123. // VarFields data length 32
  124. // Data count 10000
  125. // sqlite create table use time 1.6279ms
  126. // sqlite create index use time 0s
  127. // generate maps 10000 use time 1.1913207s
  128. // sqlite insert with transaction 10000 use time 1.9912916s
  129. // sqlite insert with transaction 10000 use time 1.9434772s
  130. // sqlite insert immediately prepare 10000 use time 2.0023365s
  131. // sqlite insert immediately 10000 use time 6.1372897s
  132. // sqlite select query all use time 746.4µs
  133. // sqlite fetch data 40000 use time 9.9554222s
  134. // put id-data maps 10000 use time 17.2197ms
  135. // fetch maps data ids 10000 use time 6.8757ms
  136. // fetch maps data 10000 use time 1.0318ms
  137. //
  138. // GOMAXPROCS 4
  139. // Fields count 104
  140. // Empty Fields count 100
  141. // VarFields data length 32
  142. // Data count 10000
  143. // sqlite create table use time 2.6123ms
  144. // sqlite create index use time 0s
  145. // generate maps 10000 use time 932.7881ms
  146. // sqlite insert with transaction 10000 use time 1.9001722s
  147. // sqlite insert with transaction 10000 use time 1.887692s
  148. // sqlite insert immediately prepare 10000 use time 2.0469167s
  149. // sqlite insert immediately 10000 use time 3.6564142s
  150. // sqlite select query all use time 432.8µs
  151. // sqlite fetch data 40000 use time 8.4194779s
  152. // put id-data maps 10000 use time 15.1188ms
  153. // fetch maps data ids 10000 use time 5.1524ms
  154. // fetch maps data 10000 use time 167.9µs
  155. //
  156. // GOMAXPROCS 8
  157. // Fields count 104
  158. // Empty Fields count 100
  159. // VarFields data length 32
  160. // Data count 10000
  161. // sqlite create table use time 2.1335ms
  162. // sqlite create index use time 0s
  163. // generate maps 10000 use time 874.8548ms
  164. // sqlite insert with transaction 10000 use time 1.8495912s
  165. // sqlite insert with transaction 10000 use time 1.773086s
  166. // sqlite insert immediately prepare 10000 use time 1.9181581s
  167. // sqlite insert immediately 10000 use time 3.2221547s
  168. // sqlite select query all use time 235.7µs
  169. // sqlite fetch data 40000 use time 7.541716s
  170. // put id-data maps 10000 use time 14.8666ms
  171. // fetch maps data ids 10000 use time 5.7673ms
  172. // fetch maps data 10000 use time 81.5µs
  173. func TestSQLiteProfmance(t *testing.T) {
  174. runtime.GOMAXPROCS(4)
  175. println("GOMAXPROCS ", runtime.GOMAXPROCS(0))
  176. varfieldscount := 100
  177. println("Fields count ", varfieldscount+4)
  178. emptyfieldscount := 100
  179. println("Empty Fields count ", emptyfieldscount)
  180. vardatalength := 32
  181. println("VarFields data length ", vardatalength)
  182. datacount := 10000
  183. println("Data count ", datacount)
  184. st := time.Now()
  185. mdb, err := sql.Open("sqlite", ":memory:")
  186. // mdb, err := sql.Open("sqlite", "file::memory:?cache=shared")
  187. if err != nil {
  188. println("err", fmt.Sprint(err))
  189. }
  190. updatefields := "name=?,value=?,desc=?"
  191. fields := "id,name,value,desc"
  192. askmarks := "?,?,?,?"
  193. for i := 1; i <= varfieldscount; i++ {
  194. fields += ",var" + strconv.Itoa(i)
  195. askmarks += ",?"
  196. updatefields += ",var" + strconv.Itoa(i) + "=?"
  197. }
  198. allfields := fields
  199. for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
  200. allfields += ",var" + strconv.Itoa(i)
  201. }
  202. stmt, err := mdb.Prepare("create table if not exists test(" + allfields + ")")
  203. if err != nil {
  204. println("err", fmt.Sprint(err))
  205. return
  206. }
  207. rslt, err := stmt.Exec()
  208. if err != nil {
  209. println("err", fmt.Sprint(err))
  210. return
  211. }
  212. if rslt == nil {
  213. println("sqlite init table return nil")
  214. } else {
  215. id, err := rslt.LastInsertId()
  216. if err != nil {
  217. println("err", fmt.Sprint(err))
  218. return
  219. }
  220. ra, err := rslt.RowsAffected()
  221. if err != nil {
  222. println("err", fmt.Sprint(err))
  223. return
  224. }
  225. if id != 0 || ra != 0 {
  226. println("sqlite init table return ", id, ra)
  227. }
  228. }
  229. println("sqlite create table use time ", time.Since(st).String())
  230. st = time.Now()
  231. stmt, err = mdb.Prepare("create index test_id_1 on test (id)")
  232. if err != nil {
  233. println("err", fmt.Sprint(err))
  234. return
  235. }
  236. rslt, err = stmt.Exec()
  237. if err != nil {
  238. println("err", fmt.Sprint(err))
  239. return
  240. }
  241. if rslt == nil {
  242. println("sqlite init table index return nil")
  243. } else {
  244. id, err := rslt.LastInsertId()
  245. if err != nil {
  246. println("err", fmt.Sprint(err))
  247. return
  248. }
  249. ra, err := rslt.RowsAffected()
  250. if err != nil {
  251. println("err", fmt.Sprint(err))
  252. return
  253. }
  254. if id != 0 || ra != 0 {
  255. println("sqlite init table index return ", id, ra)
  256. }
  257. }
  258. println("sqlite create index use time ", time.Since(st).String())
  259. st = time.Now()
  260. data := []map[string]interface{}{}
  261. for i := 1; i <= datacount; i++ {
  262. m := map[string]interface{}{}
  263. m["id"] = i
  264. m["name"] = fmt.Sprint("name", i)
  265. m["value"] = 1.23456789 * float64(i)
  266. m["desc"] = strings.Repeat(fmt.Sprint("desc", i, "."), 10)
  267. for vi := 1; vi <= varfieldscount; vi++ {
  268. bs := make([]byte, vardatalength+rand.Intn(10)-5)
  269. for bsi := 0; bsi < len(bs); bsi++ {
  270. bs[bsi] = byte(32 + rand.Intn(95))
  271. }
  272. m["var"+strconv.Itoa(vi)] = string(bs)
  273. }
  274. data = append(data, m)
  275. // if i%10000 == 0 {
  276. // println("generate maps ", i, " use time ", time.Since(st).String())
  277. // }
  278. }
  279. println("generate maps ", datacount, " use time ", time.Since(st).String())
  280. st = time.Now()
  281. {
  282. mdb.Exec("PRAGMA synchronous = OFF") // 这个跟写文件相关,内存模式没用
  283. mdb.Exec("begin")
  284. stmt, err = mdb.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
  285. if err != nil {
  286. println("err", fmt.Sprint(err))
  287. return
  288. }
  289. for _, d := range data {
  290. args := []interface{}{
  291. d["id"],
  292. d["name"],
  293. d["value"],
  294. d["desc"]}
  295. for vi := 1; vi <= varfieldscount; vi++ {
  296. args = append(args, d["var"+strconv.Itoa(vi)])
  297. }
  298. rslt, err = stmt.Exec(args...)
  299. if err != nil {
  300. println("err", fmt.Sprint(err))
  301. }
  302. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  303. // if (i+1)%10000 == 0 {
  304. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  305. // }
  306. }
  307. mdb.Exec("commit")
  308. mdb.Exec("PRAGMA synchronous = NORMAL") // 这个跟写文件相关,内存模式没用
  309. println("sqlite insert with transaction ", len(data), " use time ", time.Since(st).String())
  310. }
  311. st = time.Now()
  312. tx, err := mdb.Begin()
  313. if err != nil {
  314. println("err", fmt.Sprint(err))
  315. return
  316. }
  317. stmt, err = tx.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
  318. if err != nil {
  319. println("err", fmt.Sprint(err))
  320. return
  321. }
  322. for _, d := range data {
  323. args := []interface{}{
  324. d["id"],
  325. d["name"],
  326. d["value"],
  327. d["desc"]}
  328. for vi := 1; vi <= varfieldscount; vi++ {
  329. args = append(args, d["var"+strconv.Itoa(vi)])
  330. }
  331. rslt, err = stmt.Exec(args...)
  332. if err != nil {
  333. println("err", fmt.Sprint(err))
  334. }
  335. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  336. // if (i+1)%10000 == 0 {
  337. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  338. // }
  339. }
  340. tx.Commit()
  341. println("sqlite insert with transaction ", len(data), " use time ", time.Since(st).String())
  342. st = time.Now()
  343. stmt, err = mdb.Prepare("insert into test(" + fields + ") values(" + askmarks + ")")
  344. if err != nil {
  345. println("err", fmt.Sprint(err))
  346. return
  347. }
  348. for _, d := range data {
  349. args := []interface{}{
  350. d["id"],
  351. d["name"],
  352. d["value"],
  353. d["desc"]}
  354. for vi := 1; vi <= varfieldscount; vi++ {
  355. args = append(args, d["var"+strconv.Itoa(vi)])
  356. }
  357. rslt, err = stmt.Exec(args...)
  358. if err != nil {
  359. println("err", fmt.Sprint(err))
  360. }
  361. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  362. // if (i+1)%10000 == 0 {
  363. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  364. // }
  365. }
  366. println("sqlite insert immediately prepare ", len(data), " use time ", time.Since(st).String())
  367. st = time.Now()
  368. for _, d := range data {
  369. args := []interface{}{
  370. d["id"],
  371. d["name"],
  372. d["value"],
  373. d["desc"]}
  374. for vi := 1; vi <= varfieldscount; vi++ {
  375. args = append(args, d["var"+strconv.Itoa(vi)])
  376. }
  377. sql := "insert into test(" + fields + ") values("
  378. for i, arg := range args {
  379. if i > 0 {
  380. sql += ","
  381. }
  382. switch a := arg.(type) {
  383. case string:
  384. sql += "'" + strings.ReplaceAll(a, "'", "''") + "'"
  385. default:
  386. sql += fmt.Sprint(arg)
  387. }
  388. }
  389. sql += ")"
  390. rslt, err = mdb.Exec(sql)
  391. if err != nil {
  392. println("err", fmt.Sprint(err))
  393. }
  394. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  395. // if (i+1)%10000 == 0 {
  396. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  397. // }
  398. }
  399. println("sqlite insert immediately ", len(data), " use time ", time.Since(st).String())
  400. st = time.Now()
  401. upsertSql := `BEGIN TRANSACTION;
  402. DELETE FROM test WHERE id=?;
  403. INSERT INTO test (` + fields + `) VALUES (` + askmarks + `);
  404. COMMIT;`
  405. upsertstmt, err := mdb.Prepare(upsertSql)
  406. if err != nil {
  407. println("err", fmt.Sprint(err))
  408. }
  409. for _, d := range data {
  410. args := []interface{}{
  411. d["id"],
  412. d["id"],
  413. d["name"],
  414. d["value"],
  415. d["desc"]}
  416. for vi := 1; vi <= varfieldscount; vi++ {
  417. args = append(args, d["var"+strconv.Itoa(vi)])
  418. }
  419. rslt, err = upsertstmt.Exec(args...)
  420. if err != nil {
  421. println("err", fmt.Sprint(err))
  422. }
  423. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  424. // if (i+1)%10000 == 0 {
  425. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  426. // }
  427. }
  428. println("sqlite upsert(del+insert) immediately prepare ", len(data), " use time ", time.Since(st).String())
  429. st = time.Now()
  430. updateSql := `UPDATE test SET ` + updatefields + ` WHERE id=?`
  431. updatestmt, err := mdb.Prepare(updateSql)
  432. if err != nil {
  433. println("err", fmt.Sprint(err))
  434. }
  435. for _, d := range data {
  436. args := []interface{}{
  437. d["name"],
  438. d["value"],
  439. d["desc"]}
  440. for vi := 1; vi <= varfieldscount; vi++ {
  441. args = append(args, d["var"+strconv.Itoa(vi)])
  442. }
  443. args = append(args, d["id"])
  444. rslt, err = updatestmt.Exec(args...)
  445. if err != nil {
  446. println("err", fmt.Sprint(err))
  447. }
  448. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  449. // if (i+1)%10000 == 0 {
  450. // println("sqlite insert ", (i + 1), " use time ", time.Since(st).String())
  451. // }
  452. }
  453. println("sqlite update immediately prepare ", len(data), " use time ", time.Since(st).String())
  454. st = time.Now()
  455. stmt, err = mdb.Prepare("select * from test")
  456. if err != nil {
  457. println("err", fmt.Sprint(err))
  458. return
  459. }
  460. rows, err := stmt.Query()
  461. if err != nil {
  462. println("err", fmt.Sprint(err))
  463. return
  464. }
  465. println("sqlite select query all", " use time ", time.Since(st).String())
  466. defer func() { _ = rows.Close() }()
  467. cols, err := rows.Columns()
  468. if err != nil {
  469. println("err", fmt.Sprint(err))
  470. return
  471. }
  472. colTypes, err := rows.ColumnTypes()
  473. if err != nil {
  474. println("err", fmt.Sprint(err))
  475. return
  476. }
  477. types := make([]reflect.Type, len(colTypes))
  478. for i, tp := range colTypes {
  479. st := tp.ScanType()
  480. if st == nil {
  481. continue
  482. }
  483. types[i] = st
  484. }
  485. data = []map[string]interface{}{}
  486. for rows.Next() {
  487. values := make([]interface{}, len(cols))
  488. for i := range values {
  489. if types[i] == nil {
  490. values[i] = &[]byte{}
  491. } else {
  492. values[i] = reflect.New(types[i]).Interface()
  493. }
  494. }
  495. if err = rows.Scan(values...); err != nil {
  496. println("err", fmt.Sprint(err))
  497. return
  498. }
  499. m := make(map[string]interface{})
  500. for i, v := range values {
  501. if v == nil {
  502. //values[i] = nil
  503. m[colTypes[i].Name()] = nil
  504. } else {
  505. n, ok := colTypes[i].Length()
  506. m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
  507. }
  508. }
  509. data = append(data, m)
  510. // if len(data)%10000 == 0 {
  511. // println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
  512. // }
  513. }
  514. println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
  515. st = time.Now()
  516. memdataset := map[string]map[string]interface{}{}
  517. for _, d := range data {
  518. id := cast.ToString(d["id"])
  519. memdataset[id] = d
  520. }
  521. println("put id-data maps ", len(memdataset), " use time ", time.Since(st).String())
  522. st = time.Now()
  523. ids := []string{}
  524. for id, d := range memdataset {
  525. if id == d["id"] {
  526. ids = append(ids, id)
  527. }
  528. }
  529. println("fetch maps data ids ", len(ids), " use time ", time.Since(st).String())
  530. st = time.Now()
  531. data = []map[string]interface{}{}
  532. for _, id := range ids {
  533. d := memdataset[id]
  534. data = append(data, d)
  535. }
  536. println("fetch maps data ", len(data), " use time ", time.Since(st).String())
  537. }
  538. func TestSQLiteJSON(t *testing.T) {
  539. // sqlite 内存表结构中字段类型只有 int64 float64 string, string没有长度限制
  540. // create table 中指定的类型没有意义,不影响数据插入
  541. // 实际数据类型是 由 第一次插入的数据的类型 决定的
  542. // 查询时,后续数据会强制转换为该类型,转不过去会报错,如将非数字字符串转换为数值
  543. mdb, err := sql.Open("sqlite", ":memory:")
  544. if err != nil {
  545. println("err", fmt.Sprint(err))
  546. return
  547. }
  548. stmt, err := mdb.Prepare(`CREATE TABLE TEST(
  549. ID INT PRIMARY KEY NOT NULL,
  550. NAME TEXT NOT NULL,
  551. VALUE REAL NOT NULL,
  552. INTVALUE INT NOT NULL,
  553. DESC CHAR(1)
  554. )`)
  555. if err != nil {
  556. println("err", fmt.Sprint(err))
  557. return
  558. }
  559. rslt, err := stmt.Exec()
  560. if err != nil {
  561. println("err", fmt.Sprint(err))
  562. return
  563. }
  564. println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  565. stmt, err = mdb.Prepare("insert into test(id,name,intvalue,value,desc) values(?,?,?,?,?)")
  566. if err != nil {
  567. println("err", fmt.Sprint(err))
  568. return
  569. }
  570. for i := 1; i < 10; i++ {
  571. id := string([]byte{})
  572. for n := 0; n < 16; n++ {
  573. id = id + string('a'+byte(n+i-1))
  574. }
  575. name := int64(30 + i)
  576. floatvalue := 12345 + (i-1)*10000
  577. var intvalue interface{}
  578. intvalue = 1.2345 * float32(i)
  579. if i%3 == 1 {
  580. intvalue = "--12345--"
  581. } else if i%3 == 2 {
  582. intvalue = 123450 + i
  583. }
  584. bs, _ := json.MarshalIndent(map[string]interface{}{
  585. "value": floatvalue,
  586. }, "", " ")
  587. desc := string(bs)
  588. rslt, err = stmt.Exec(id, name, intvalue, floatvalue, desc)
  589. if err != nil {
  590. println("err", fmt.Sprint(err))
  591. }
  592. println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  593. }
  594. {
  595. stmt, err = mdb.Prepare(`select * from test`)
  596. if err != nil {
  597. println("err", fmt.Sprint(err))
  598. return
  599. }
  600. rows, err := stmt.Query()
  601. if err != nil {
  602. println("err", fmt.Sprint(err))
  603. return
  604. }
  605. defer func() { _ = rows.Close() }()
  606. cols, err := rows.Columns()
  607. if err != nil {
  608. println("err", fmt.Sprint(err))
  609. return
  610. }
  611. colTypes, err := rows.ColumnTypes()
  612. if err != nil {
  613. println("err", fmt.Sprint(err))
  614. return
  615. }
  616. types := make([]reflect.Type, len(colTypes))
  617. for i, tp := range colTypes {
  618. st := tp.ScanType()
  619. if st == nil {
  620. continue
  621. }
  622. types[i] = st
  623. }
  624. for rows.Next() {
  625. values := make([]interface{}, len(cols))
  626. for i := range values {
  627. values[i] = reflect.New(types[i]).Interface()
  628. }
  629. if err = rows.Scan(values...); err != nil {
  630. println("err", fmt.Sprint(err))
  631. return
  632. }
  633. m := make(map[string]interface{})
  634. for i, v := range values {
  635. if v == nil {
  636. //values[i] = nil
  637. m[colTypes[i].Name()] = nil
  638. } else {
  639. n, ok := colTypes[i].Length()
  640. m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
  641. }
  642. }
  643. bs, _ := json.MarshalIndent(m, "", " ")
  644. println("values", string(bs))
  645. }
  646. }
  647. stmt, err = mdb.Prepare(`select json_group_array(json_object(
  648. 'id', id,
  649. 'name', name,
  650. 'value', value)) as json
  651. from test
  652. where json_extract(desc, '$.value') > 20000 and json_extract(desc, '$.value') < 50000`)
  653. if err != nil {
  654. println("err", fmt.Sprint(err))
  655. return
  656. }
  657. rows, err := stmt.Query()
  658. if err != nil {
  659. println("err", fmt.Sprint(err))
  660. return
  661. }
  662. defer func() { _ = rows.Close() }()
  663. cols, err := rows.Columns()
  664. if err != nil {
  665. println("err", fmt.Sprint(err))
  666. return
  667. }
  668. colTypes, err := rows.ColumnTypes()
  669. if err != nil {
  670. println("err", fmt.Sprint(err))
  671. return
  672. }
  673. types := make([]reflect.Type, len(colTypes))
  674. for i, tp := range colTypes {
  675. st := tp.ScanType()
  676. if st == nil {
  677. continue
  678. }
  679. types[i] = st
  680. }
  681. for rows.Next() {
  682. values := make([]interface{}, len(cols))
  683. for i := range values {
  684. values[i] = reflect.New(types[i]).Interface()
  685. }
  686. if err = rows.Scan(values...); err != nil {
  687. println("err", fmt.Sprint(err))
  688. return
  689. }
  690. m := make(map[string]interface{})
  691. for i, v := range values {
  692. if v == nil {
  693. //values[i] = nil
  694. m[colTypes[i].Name()] = nil
  695. } else {
  696. n, ok := colTypes[i].Length()
  697. m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
  698. }
  699. }
  700. bs, _ := json.MarshalIndent(m, "", " ")
  701. println("values", string(bs))
  702. }
  703. }
  704. func TestSQLiteProfmanceMultiTable(t *testing.T) {
  705. runtime.GOMAXPROCS(4)
  706. println("GOMAXPROCS ", runtime.GOMAXPROCS(0))
  707. tablecount := 10000
  708. println("Tables count ", tablecount)
  709. varfieldscount := 100
  710. println("VarFields count ", varfieldscount+4)
  711. emptyfieldscount := 100
  712. println("EmptyFields count ", emptyfieldscount)
  713. vardatalength := 32
  714. println("VarFields data length ", vardatalength)
  715. tableindexcount := 100
  716. println("TableIndex count ", tableindexcount)
  717. datacount := 10000
  718. println("Data count ", datacount)
  719. mdb, err := sql.Open("sqlite", ":memory:")
  720. // mdb, err := sql.Open("sqlite", "file::memory:?cache=shared")
  721. if err != nil {
  722. println("err", fmt.Sprint(err))
  723. }
  724. st := time.Now()
  725. for ti := 1; ti < tablecount; ti++ {
  726. tablename := fmt.Sprint("test", ti)
  727. fields := []string{"id", "name", "value", "desc"}
  728. varfields := strings.Join(fields, ",")
  729. askmarks := "?" + strings.Repeat(",?", len(fields)-1)
  730. for i := 1; i <= varfieldscount; i++ {
  731. fields = append(fields, "var"+strconv.Itoa(i))
  732. varfields += ",var" + strconv.Itoa(i)
  733. askmarks += ",?"
  734. }
  735. allfields := varfields
  736. for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
  737. fields = append(fields, "var"+strconv.Itoa(i))
  738. allfields += ",var" + strconv.Itoa(i)
  739. }
  740. st := time.Now()
  741. stmt, err := mdb.Prepare("create table if not exists " + tablename + "(" + allfields + ")")
  742. if err != nil {
  743. println("err", fmt.Sprint(err))
  744. return
  745. }
  746. rslt, err := stmt.Exec()
  747. if err != nil {
  748. println("err", fmt.Sprint(err))
  749. return
  750. }
  751. if rslt == nil {
  752. println("sqlite init table return nil")
  753. } else {
  754. id, err := rslt.LastInsertId()
  755. if err != nil {
  756. println("err", fmt.Sprint(err))
  757. return
  758. }
  759. ra, err := rslt.RowsAffected()
  760. if err != nil {
  761. println("err", fmt.Sprint(err))
  762. return
  763. }
  764. if id != 0 || ra != 0 {
  765. println("sqlite init table return ", id, ra)
  766. }
  767. }
  768. println("sqlite create table", tablename, "use time ", time.Since(st).String())
  769. }
  770. println("sqlite create table", tablecount, "done, use time ", time.Since(st).String())
  771. st = time.Now()
  772. for ti := 1; ti < tablecount; ti++ {
  773. tablename := fmt.Sprint("test", ti)
  774. fields := []string{"id", "name", "value", "desc"}
  775. varfields := strings.Join(fields, ",")
  776. askmarks := "?" + strings.Repeat(",?", len(fields)-1)
  777. for i := 1; i <= varfieldscount; i++ {
  778. fields = append(fields, "var"+strconv.Itoa(i))
  779. varfields += ",var" + strconv.Itoa(i)
  780. askmarks += ",?"
  781. }
  782. allfields := varfields
  783. for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
  784. fields = append(fields, "var"+strconv.Itoa(i))
  785. allfields += ",var" + strconv.Itoa(i)
  786. }
  787. st = time.Now()
  788. for i, field := range fields {
  789. if i > tableindexcount {
  790. break
  791. }
  792. stmt, err := mdb.Prepare("create index " + tablename + "_" + field + " on " + tablename + " (" + field + ")")
  793. if err != nil {
  794. println("err", fmt.Sprint(err))
  795. return
  796. }
  797. rslt, err := stmt.Exec()
  798. if err != nil {
  799. println("err", fmt.Sprint(err))
  800. return
  801. }
  802. if rslt == nil {
  803. println("sqlite init table index return nil")
  804. } else {
  805. id, err := rslt.LastInsertId()
  806. if err != nil {
  807. println("err", fmt.Sprint(err))
  808. return
  809. }
  810. ra, err := rslt.RowsAffected()
  811. if err != nil {
  812. println("err", fmt.Sprint(err))
  813. return
  814. }
  815. if id != 0 || ra != 0 {
  816. println("sqlite init table index return ", id, ra)
  817. }
  818. }
  819. }
  820. println("sqlite create index for table "+tablename+" use time ", time.Since(st).String())
  821. }
  822. println("sqlite create table index", tablecount, "done, use time ", time.Since(st).String())
  823. st = time.Now()
  824. data := []map[string]interface{}{}
  825. {
  826. st = time.Now()
  827. for i := 1; i <= datacount; i++ {
  828. m := map[string]interface{}{}
  829. m["id"] = i
  830. m["name"] = fmt.Sprint("name", i)
  831. m["value"] = 1.23456789 * float64(i)
  832. m["desc"] = strings.Repeat(fmt.Sprint("desc", i, "."), 10)
  833. for vi := 1; vi <= varfieldscount; vi++ {
  834. bs := make([]byte, vardatalength+rand.Intn(10)-5)
  835. for bsi := 0; bsi < len(bs); bsi++ {
  836. bs[bsi] = byte(32 + rand.Intn(95))
  837. }
  838. m["var"+strconv.Itoa(vi)] = string(bs)
  839. }
  840. data = append(data, m)
  841. if i%1000 == 0 {
  842. println("generate maps ", i, " use time ", time.Since(st).String())
  843. }
  844. }
  845. println("generate maps ", datacount, " use time ", time.Since(st).String())
  846. st = time.Now()
  847. memdataset := map[string]map[string]interface{}{}
  848. for _, d := range data {
  849. id := cast.ToString(d["id"])
  850. memdataset[id] = d
  851. }
  852. println("put id-data maps ", len(memdataset), " use time ", time.Since(st).String())
  853. st = time.Now()
  854. ids := []string{}
  855. for id, d := range memdataset {
  856. if id == cast.ToString(d["id"]) {
  857. ids = append(ids, id)
  858. }
  859. }
  860. println("fetch maps data ids ", len(ids), " use time ", time.Since(st).String())
  861. st = time.Now()
  862. data = []map[string]interface{}{}
  863. for _, id := range ids {
  864. d := memdataset[id]
  865. data = append(data, d)
  866. }
  867. println("fetch maps data ", len(data), " use time ", time.Since(st).String())
  868. }
  869. for ti := 1; ti < tablecount; ti++ {
  870. tablename := fmt.Sprint("test", ti)
  871. fields := []string{"id", "name", "value", "desc"}
  872. varfields := strings.Join(fields, ",")
  873. askmarks := "?" + strings.Repeat(",?", len(fields)-1)
  874. for i := 1; i <= varfieldscount; i++ {
  875. fields = append(fields, "var"+strconv.Itoa(i))
  876. varfields += ",var" + strconv.Itoa(i)
  877. askmarks += ",?"
  878. }
  879. allfields := varfields
  880. for i := varfieldscount + 1; i <= varfieldscount+emptyfieldscount; i++ {
  881. fields = append(fields, "var"+strconv.Itoa(i))
  882. allfields += ",var" + strconv.Itoa(i)
  883. }
  884. { // insert
  885. st = time.Now()
  886. stmt, err := mdb.Prepare("insert into " + tablename + "(" + varfields + ") values(" + askmarks + ")")
  887. if err != nil {
  888. println("err", fmt.Sprint(err))
  889. return
  890. }
  891. i := 0
  892. for _, d := range data {
  893. i = i + 1
  894. args := []interface{}{
  895. d["id"],
  896. d["name"],
  897. d["value"],
  898. d["desc"]}
  899. for vi := 1; vi <= varfieldscount; vi++ {
  900. args = append(args, d["var"+strconv.Itoa(vi)])
  901. }
  902. _, err := stmt.Exec(args...)
  903. if err != nil {
  904. println("err", fmt.Sprint(err))
  905. }
  906. // println("rslt", fmt.Sprint(rslt.LastInsertId()), fmt.Sprint(rslt.RowsAffected()))
  907. if i%1000 == 0 {
  908. println("sqlite insert ", i, " use time ", time.Since(st).String())
  909. }
  910. }
  911. println("sqlite insert ", tablename, len(data), " use time ", time.Since(st).String())
  912. }
  913. { // select
  914. st = time.Now()
  915. stmt, err := mdb.Prepare("select " + varfields + " from " + tablename)
  916. if err != nil {
  917. println("err", fmt.Sprint(err))
  918. return
  919. }
  920. rows, err := stmt.Query()
  921. if err != nil {
  922. println("err", fmt.Sprint(err))
  923. return
  924. }
  925. println("sqlite select query all", " use time ", time.Since(st).String())
  926. defer func() { _ = rows.Close() }()
  927. cols, err := rows.Columns()
  928. if err != nil {
  929. println("err", fmt.Sprint(err))
  930. return
  931. }
  932. colTypes, err := rows.ColumnTypes()
  933. if err != nil {
  934. println("err", fmt.Sprint(err))
  935. return
  936. }
  937. types := make([]reflect.Type, len(colTypes))
  938. for i, tp := range colTypes {
  939. st := tp.ScanType()
  940. if st == nil {
  941. continue
  942. }
  943. types[i] = st
  944. }
  945. data := []map[string]interface{}{}
  946. for rows.Next() {
  947. values := make([]interface{}, len(cols))
  948. for i := range values {
  949. if types[i] == nil {
  950. values[i] = &[]byte{}
  951. } else {
  952. values[i] = reflect.New(types[i]).Interface()
  953. }
  954. }
  955. if err = rows.Scan(values...); err != nil {
  956. println("err", fmt.Sprint(err))
  957. return
  958. }
  959. m := make(map[string]interface{})
  960. for i, v := range values {
  961. if v == nil {
  962. //values[i] = nil
  963. m[colTypes[i].Name()] = nil
  964. } else {
  965. n, ok := colTypes[i].Length()
  966. m[colTypes[i].Name()] = fmt.Sprint(types[i], "[", n, "]", ok, ":", reflect.ValueOf(v).Elem().Interface())
  967. }
  968. }
  969. data = append(data, m)
  970. // if len(data)%10000 == 0 {
  971. // println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
  972. // }
  973. }
  974. println("sqlite fetch data ", len(data), " use time ", time.Since(st).String())
  975. }
  976. }
  977. }