美文网首页
python3--DB--优化insert数据时间

python3--DB--优化insert数据时间

作者: w_dll | 来源:发表于2021-04-18 10:18 被阅读0次

    如图, 之前插入的时间是207s, 优化后执行时间为58s




    主要是之前做的比较粗, 直接插入一条, commit一次;
    这样效率太低;
    我之前写了一个类, 操作sqlite和mysql;
    类如下:

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    import pymysql
    import sqlite3
    
    def dict_factory(cursor, row):
      d = {}
      for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
      return d
    class MySqlTools:
      def __init__(self, dbtype, **db_conf):
        self.dbtype = dbtype
        self.db_conf = db_conf
        if dbtype == 'mysql':
          db = db_conf.get('db', None)
          passwd = db_conf.get('passwd', None)
          if db == None or passwd == None:
            print('mysql need define db, passwd!')
            sys.exit(1)
          host = db_conf.get('host', 'localhost')
          user = db_conf.get('user', 'root')
          port = db_conf.get('port', 3306)
          charset = db_conf.get('cherset', 'utf8')
          conn = pymysql.connect(host=host,\
                 user=user,\
                 passwd=passwd,\
                 db=db,\
                 port=port, \
                 charset=charset)
        elif dbtype == 'sqlite':
          db = db_conf.get('db', None)
          if db == None:
            print('sqlite need define db!')
            sys.exit(1)
          conn = sqlite3.connect(db)
          conn.text_factory = str
          conn.row_factory = dict_factory
        self.conn = conn
      def select(self, t_sql):
        if self.dbtype == 'mysql':
          cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
        elif self.dbtype == 'sqlite':
          cur = self.conn.cursor()
        try:
          cur.execute(t_sql)
        except Exception as e:
          print(e)
          return 'fail'
        result_of_sql = cur.fetchall()
        cur.close()
        return result_of_sql
      def exec(self, t_sql):
        if self.dbtype == 'mysql':
          cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
        elif self.dbtype == 'sqlite':
          cur = self.conn.cursor()
        try:
          res = cur.execute(t_sql)
          self.conn.commit()
        except Exception as e:
          self.conn.rollback()
          print(e)
          return 'fail'
        cur.close()
        return ('success %s' % res)
      def insert(self, sql_list, commit=1):
        if self.dbtype == 'mysql':
          cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
        elif self.dbtype == 'sqlite':
          cur = self.conn.cursor()
        while sql_list:
          range_times = commit
          if len(sql_list) < range_times:
            range_times = len(sql_list)
          for i in range(range_times):
            t_sql = sql_list.pop(0)
            try:
              cur.execute(t_sql)
            except Exception as e:
              print(e)
              cur.close()
              return 'fail'
          try:
            self.conn.commit()
          except Exception as e:
            print(e)
            self.conn.rollback()
            cur.close()
            return 'fail'
        cur.close()
    
      def close(self):
        self.conn.close()
    

    目前把insert 单独写了一个方法, 之前用的是exec方法;
    insert方法两个外部参数, sql语句列表和执行多少条再提交;
    当然根据测试, 1000条数据一次提交和300条数据一次提交, 速度并无太大差别;
    这个还是要多测试才能找到合适的。。
    测试实例如下;

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    import yaml
    import sys, os, time
    from package.mytool import MySqlTools
    
    def init_conf(file_name):
      f = open(file_name, 'r', encoding="utf-8")
      data = yaml.load(f, Loader=yaml.FullLoader)
      f.close()
      return data
    
    def insert_value(table_name, data):
      sql_list = []
      for i in data:
        t_sql = "insert into %s(%s) values(%s);"
        v1, v2 = '', ''
        for j in i:
          if not v1 and not v2:
            v1, v2 = str(j), '"'+str(i[j])+'"'
          else:
            v1, v2 = v1+','+str(j), v2+','+'"'+str(i[j])+'"'
        t_sql = (t_sql % (table_name, v1, v2))
        sql_list.append(t_sql)
      return sql_list
    
    if __name__ == '__main__':
      base_dir = sys.path[0]
      os.chdir(base_dir)
      data = init_conf('config.yml')
      mysql_conf = data.get('mysql', None)
      mysql_conn = MySqlTools('mysql', **mysql_conf)
      sqlite_conn = MySqlTools('sqlite', db='app-info.db')
      '''初始化
      t_sql = "create table if not exists app_info \
              (id INTEGER PRIMARY KEY AUTO_INCREMENT,busniess_name VARCHAR(100),\
              app_name VARCHAR(100),app_cluster VARCHAR(100),\
              app_ip VARCHAR(100),data_src VARCHAR(100),app_nameid VARCHAR(100),app_pgm VARCHAR(100));"
      mysql_conn.exec(t_sql)
      '''
      t_sql = "select busniess_name, app_name, app_cluster, app_ip, data_src, \
              app_nameid, app_pgm from app_info;"
      res = sqlite_conn.select(t_sql)
      sql_list = insert_value('app_info', res)
      start_time = time.time()
      mysql_conn.insert(sql_list, 200)
      end_time = time.time()
      exec_time = end_time - start_time
      print('exec time == > %s \n' % (exec_time))
    
    

    相关文章

      网友评论

          本文标题:python3--DB--优化insert数据时间

          本文链接:https://www.haomeiwen.com/subject/fpbmlltx.html