0

単語の配列を取得し、foreach を介してすべての単語を DB に挿入する必要があるという問題がありますが、全体の実行が遅すぎます。

foreach($words as $word) {
    // even more checks
    if(strlen($word) < 3) continue;
    $word = $this->db->escapeString(strtolower($word));

    // word not found?
    $result = $this->db->querySingle("SELECT id FROM words WHERE word = '{$word}'");
    if(!$result) {
        $this->db->exec("INSERT INTO words (word) VALUES ('{$word}')");
        $this->db->exec("INSERT INTO search (reply, word) VALUES ('{$id}', '{$this->db->lastInsertRowID()}')");

    // word found
    } else $this->db->exec("INSERT INTO search (reply, word) VALUES ('{$id}', '{$result}')");
}

基本的に、 $words = array('hello', 'kitten'); としましょう。その foreach 内で、最初の単語 (hello) を取得し、words テーブルに存在するかどうかを確認します。単語が見つからない場合は、そこに挿入し、foreach 内で変更されない変数 $id を持つ別のテーブルにも挿入します。ただし、単語が見つかった場合は、2 番目のテーブルに直接挿入されます。その後、2 番目の単語 (kitten) を取り、同じことを行います。

sqlite3 で php5 を使用する

$this->db = new \SQLite3(ROOT . DS . 'db' . DS . 'app.db');

問題のテーブルは非常に軽いです

CREATE TABLE words (id INTEGER PRIMARY KEY AUTOINCREMENT, word TEXT);

CREATE TABLE search (reply INTEGER, word INTEGER);
CREATE INDEX search_reply_idx ON search (reply);
CREATE INDEX search_word_idx ON search (word);

これは、10 ~ 15 語の場合はほとんどの場合問題なく動作しますが、150 語を超える場合は 8 秒ほど遅くなります。クエリを 1 つだけに結合できますか? 何か不足していますか?

ありがとう。

4

2 に答える 2

2

この方法は、SQLite がこの挿入構文をサポートしているという前提に基づいています (この構文は MySQL で機能します)。

INSERT INTO table (column) VALUES ('value1'), ('value2'), ('value3'), ('valueN');

できることは、PHP を使用してSELECTステートメントのロジックを使用して SQL 挿入文字列を作成し、最後に 2 つのクエリを実行することです。単語テーブルに 1 つ、検索テーブルに 1 つ:

$sql_words = 'INSERT INTO words (word) VALUES ';
$sql_search = 'INSERT INTO search (reply, word) VALUES ';

$count = count($words);
$i = 0;
$last_insert_id = '';
$delim = '';

foreach ($words as $word)
{
    $result = $this->db->querySingle("SELECT id FROM words WHERE word = '{$word}'");

    if ($i < $count) {
        $delim = ', ';
    } else {
        $delim = '';
    }

    if ($result) {
        $sql_search .= "('{$result}','{$word}')".$delim;
    } else {
        $sql_words .= "('{$word}')".$delim;
        $sql_search .= "('{$result}','{$last_insert_id}')".$delim;
    }

    $last_insert_id = $result;
    $i++;
}

$this->db-exec($sql_words);
$this->db->exec($sql_search);

このコードの有効性については、私は確信が持てず、どこ$idから来たのか少し混乱し、$result.

于 2013-11-14T01:37:07.140 に答える