postgresql:解决in的效率问题

 数据库中进行表的链接查询比使用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 单位:纳秒)

 

转载于:https://www.cnblogs.com/zp900704/p/7694125.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值