首页 > 解决方案 > Mysql LOAD DATA INFILE - 越来越慢

问题描述

设置:具有 8 列的 MyISAM 表......并且每列有 1 个索引。没有外键。

数据:通过 Pymysql / LOAD 数据插入 500m+ 条记录

服务器:VPS 上的 Mariadb 10.08 和 1gb RAM(是的,我知道.. 客户的服务器,不是我的)

架构:

drop table if exists profiles;
create table profiles (
    id          bigint auto_increment primary key,
    first_name  varchar(128) NULL,
    last_name   varchar(128) NULL,
    liid        varchar(256) NOT NULL,
    city        varchar(128) NULL,
    state       varchar(128) NULL,
    country     varchar(128) NULL,
    email       varchar(512) null,
    phone       varchar(512) null
) engine=MyISAM auto_increment=0 default CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
create index liid_idx on profiles(liid);

我一次加载 1m 条记录。这是一些代码:

connection = None 
cursor = None

def execute_sql( sql ):
    global cursor
    cursor.execute( sql )
    
def open_db(mysql_user, mysql_passwd, mysql_host, mysql_db):
    global connection, cursor
    connection = MySQLdb.Connect(host=mysql_host, user=mysql_user, passwd=mysql_passwd, db=mysql_db, local_infile=True)
    cursor = connection.cursor()

    ########################################################################################
    # https://stackoverflow.com/questions/2463602/mysql-load-data-infile-acceleration
    #
    # note: this must be run as root
    ########################################################################################

    cursor.execute("set autocommit = 0;");
    cursor.execute("set unique_checks = 0;");
    cursor.execute("set foreign_key_checks = 0;");
    cursor.execute("set sql_log_bin = 0;");


def close_db():
    global connection
    connection.commit()




open_db(
        mysql_user=mysql_user,
        mysql_passwd=mysql_passwd,
        mysql_host=mysql_host,
        mysql_db=mysql_db
    )

for file in [....]:
    start = time.time()

    execute_sql(sql='''
    LOAD DATA LOCAL INFILE '{}' INTO TABLE profile FIELDS TERMINATED by '\t' ENCLOSED BY '"' (@first_name, @last_name, liid, @city, @state, @country, @email, @phone) SET first_name = NULLIF(@first_name,''), first_name = NULLIF(@first_name,''), last_name = NULLIF(@last_name,''), city = NULLIF(@city,''), state = NULLIF(@state,''), country = NULLIF(@country,''), email = NULLIF(@email,''), phone = NULLIF(@phone,'');
    '''.format(file))

    end = time.time()

    duration= end-start

    print("[mysql] duration: {} seconds".format(int(duration))

close_db()

它越来越慢。

有任何想法吗?

结果:

[mysql] 持续时间:26 秒

[mysql] 持续时间:63 秒

[mysql] 持续时间:73 秒

[mysql] 持续时间:75 秒

[mysql] 持续时间:81 秒

[mysql] 持续时间:91 秒

[mysql] 持续时间:85 秒

[mysql] 持续时间:94 秒

[mysql] 持续时间:98 秒

[mysql] 持续时间:96 秒

[mysql] 持续时间:107 秒

[mysql] 持续时间:122 秒

[mysql] 持续时间:141 秒

[mysql] 持续时间:169 秒

[mysql] 持续时间:255 秒

[mysql] 持续时间:356 秒

[mysql] 持续时间:822 秒

[mysql] 持续时间:1590 秒

[mysql] 持续时间:2454 秒

[mysql] 持续时间:3800 秒

[mysql] 持续时间:4080 秒

[mysql] 持续时间:4459 秒

[mysql] 持续时间:4879 秒

[mysql] 持续时间:4638 秒

[mysql] 持续时间:4994 秒

[mysql] 持续时间:5749 秒

[mysql] 持续时间:5047 秒

[mysql] 持续时间:5641 秒

[mysql] 持续时间:6207 秒

[mysql] 持续时间:6325 秒

[mysql] 持续时间:6772 秒

标签: pythonmysqlperformancemariadb

解决方案


推荐阅读