標籤:break values https now() split arch cas 單位 ima
資料庫中進行表的連結查詢比使用in的速度是要快的,怎樣在程式中避免使用in?
postgresql提供了regexp_split_to_table這個函數,我們可以藉助該函數避免使用in帶來的問題
使用方法:
有表A,表A中有欄位Id
使用in查詢:select * from A where id in ( xxx,xxxx,xxxx)
替換後寫法:select A.* from (select regexp_split_to_table(‘xxxx,xxx‘,‘,‘ ) as ids) as tt join A on tt.ids=A.id
分割方式隨意,上面的替換的寫法分割方式是“,”
附加:
1.建立表:CREATE TABLE gg( "Id" varchar(36));CREATE INDEX index_gg_id ON gg("Id"); CREATE TABLE ggu( "Id" varchar(36))
2.產生資料(golang代碼)
func createdata(eng *xorm.Engine) { c := make(chan int, 20) for i := 0; i < 20; i++ { eng.Exec(`insert into gg("Id") values(‘` + strings.UUID() + `‘)`) c <- 1 } i := 0 for { select { case <-c: i++ default: eng.Exec(`insert into gg("Id") values(‘` + strings.UUID() + `‘)`) c <- 1 } if i%10000 == 0 { fmt.Println(time.Now()) } if i > 1000000 { break } }}
用的uuid作為id
3.查詢
func insearchspend(eng *xorm.Engine) { ids := []string{ "752e92bc-9ac0-48e1-8dcc-e162acadfe15", "ce16c8c9-4e24-4063-98b3-9b40ad312c2f", "603bc795-92b1-4111-a7d5-3ece6861eb54", } result := make([]*gg, 0) //ids = ids[0:2] tm := time.Now() err := eng.Table("gg").In(`"Id"`, ids).Find(&result) if err != nil { fmt.Println(err.Error()) } fmt.Println(time.Now().UnixNano() - tm.UnixNano()) tm = time.Now() err = eng.Sql(`SELECT "Id" FROM (SELECT regexp_split_to_table(?,‘,‘) AS tt) AS ids JOIN gg ON ids.tt=gg."Id"`, sysstring.Join(ids, ",")).Find(&result) if err != nil { fmt.Println(err.Error()) } fmt.Println(time.Now().UnixNano() - tm.UnixNano()) tm = time.Now()}
在本地測試效能差距10倍以上,測試資料量100萬+ (上面是in,下面是regexp 單位:納秒)
postgresql:解決in的效率問題