5

以下は、 CSVファイルクライアントIDフィールドを入力として使用して、MySQLデータベースからユーザーを追加または無効にするより大きなPHPスクリプトの一部です。

関連するテーブルには、usersusers_clientsの2つがあります。後者は、ユーザーが複数のクライアントに属することができるため、ユーザーとクライアント間の関係を維持します。


これがテーブルの構造です

ユーザー構造(より多くのフィールドがあります)

id        | int(11) (primary key)
user      | varchar(100)
pass      | varchar(100)
category  | int(11)
date      | timestamp
name      | varchar(100)
email     | varchar(255)

ユーザーインデックス

SEARCH    | user        | FULLTEXT
SEARCH    | name        | FULLTEXT
SEARCH    | email       | FULLTEXT

users_clients構造

id_user   | int(11)
id_client | int(11)
status    | enum('active','inactive')


これは、CSVファイルから各ユーザーを追加するためのスクリプトの基本的なフローです。

  1. そのクライアントのユーザーが存在するかどうかを確認します。

    SELECT 
        LOWER(user)
    FROM
        users u
        INNER JOIN users_clients uc ON u.id = uc.id_user
    WHERE
        u.user = '$user'
        and uc.id_client = $id_client
    
  2. 存在しない場合は、データベースに追加してください。

    INSERT INTO 
        users ($fields,id_client)
    VALUES 
        ($values,'$id_operation')
    
  3. 挿入されたユーザーのIDを取得します。ここでmysql_insert_idのようなものを使用できることは知っていますが、競合状態についてはどうでしょうか。

    SELECT
        u.id as id
    FROM
        users u
    WHERE
        u.user = '$user'
        and u.id_client = '$id_operation'
    
  4. ユーザーを対応するクライアントに関連付けます。

    INSERT INTO
        users_clients (id_user, id_client) 
    VALUES
        ('$id_user','$id_client')
    

現在、テーブルには400.000人のユーザーがいます。このスクリプトは、500ユーザーのCVSを処理するのに10分以上かかります。

これをどのように改善して、より速くしますか?

前もって感謝します。

PD:完全な機能を見たい場合は、pastebinで入手できます。

4

2 に答える 2

6
INSERT INTO table (id,a,b,c) VALUES (5454,1,2,3)
ON DUPLICATE KEY
UPDATE table SET foo WHERE id=xyz;
  1. DBにインデックスを設定する
  2. mysqlの代わりにmysqliを使用してください
  3. 挿入したいものをすべて収集し、ここのようなプリペアドステートメント/ストアドプロシージャを使用して実行します。PHPとPDOを使用して単一のMySQLプリペアドステートメントに配列を挿入する方法
  4. 500回のSELECTを実行しないでください。データベース全体を取得し、foreach / whileループを介してデータベースを処理し、必要なものをチェックします。
  5. 上記のような構成を使用する

重要:上記のステートメントでは、列IDに一意のインデックスが必要です!!!

于 2012-06-13T18:26:29.393 に答える
2

INSERTをトランザクションにラップしmysql_insert_id()ます。別のデータベース接続に切り替えない限り、心配する必要はありません。完全に安全です。

速度が大幅に向上した結果、すべてのクエリをトランザクションにラップすることもできます。

于 2012-06-13T18:28:09.930 に答える