sql >> データベース >  >> RDS >> Mysql

mysqlの遅いクエリ

    以下は非常に高速で、1,000万行で6分強かかりますが、サンプルテーブルには本番テーブルよりもフィールドとインデックスが少ないため、使用する場合は少し時間がかかると予想してください!

    >

    注:この例はWindows OSで行われたため、Linux標準に準拠するには、パス名と\ r \nを\nに変更する必要があります!

    これが私の既存のテーブル(InnoDBエンジン)です:

    drop table if exists customers;
    create table customers
    (
    customer_id int unsigned not null auto_increment primary key,
    name varchar(255) not null,
    country_id tinyint unsigned not null default 0,
    key (country_id)
    )
    engine=innodb;
    
    mysql> select count(*) from customers;
    +----------+
    | count(*) |
    +----------+
    | 10000000 |
    +----------+
    1 row in set (1.78 sec)
    

    必要な新しいフィールドを含む新しいバージョンのテーブルを作成します:

    drop table if exists customers_new;
    create table customers_new
    (
    customer_id int unsigned not null auto_increment primary key,
    name varchar(255) not null,
    country_id tinyint unsigned not null default 0,
    split tinyint not null default 0,
    key (country_id)
    )
    engine=innodb;
    

    アップロードフォルダの場所を見つける:

    select @@secure_file_priv;
    

    データをPKオーダーで古い顧客テーブルからcsv形式にエクスポートします:

    select * into outfile 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\customers.dat'
    fields terminated by '|' optionally enclosed by '"'
    lines terminated by '\r\n'
    from customers order by customer_id;
    
    Query OK, 10000000 rows affected (17.39 sec)
    

    customer.datファイルを新しいcustomerテーブルにロードします:

    truncate table customers_new;
    
    set autocommit = 0;
    
    load data infile 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\customers.dat'
    into table customers_new
    fields terminated by '|' optionally enclosed by '"'
    lines terminated by '\r\n'
    (
    customer_id,
    name,
    country_id,
    @dummy -- represents the new split field
    )
    set
    name = nullif(name,'');
    
    commit;
    
    Query OK, 10000000 rows affected (6 min 0.14 sec)
    

    新しいテーブルに問題がないことを確認します:

    select * from customers_new order by customer_id desc limit 1;
    +-------------+-------------------+------------+-------+
    | customer_id | name              | country_id | split |
    +-------------+-------------------+------------+-------+
    |    10000000 | customer 10000000 |        218 |     0 |
    +-------------+-------------------+------------+-------+
    1 row in set (0.00 sec)
    
    insert into customers_new (name, country_id, split) values ('f00',1,1);
    Query OK, 1 row affected (0.07 sec)
    
    select * from customers_new order by customer_id desc limit 1;
    +-------------+------+------------+-------+
    | customer_id | name | country_id | split |
    +-------------+------+------------+-------+
    |    10000001 | f00  |          1 |     1 |
    +-------------+------+------------+-------+
    1 row in set (0.00 sec)
    

    古いテーブルを削除し、新しいテーブルの名前を変更します:

    drop table customers;
    Query OK, 0 rows affected (0.18 sec)
    
    rename table customers_new to customers;
    Query OK, 0 rows affected (0.05 sec)
    
    select * from customers order by customer_id desc limit 1;
    +-------------+------+------------+-------+
    | customer_id | name | country_id | split |
    +-------------+------+------------+-------+
    |    10000001 | f00  |          1 |     1 |
    +-------------+------+------------+-------+
    1 row in set (0.00 sec)
    

    それはすべての人々です!



    1. 特定のページをCodeigniterでのみログインしているユーザーに制限するためのベストプラクティスは何ですか?

    2. IPをデータベースに保存する最良の方法は?

    3. Access2016でテーブルをバックエンドデータベースにリンクする方法

    4. MySQLALTERTABLEがハングする