Php foreach中的Sql查询会降低页面速度

Php foreach中的Sql查询会降低页面速度,php,sql,sqlite,Php,Sql,Sqlite,我有一个问题,我得到了一个单词数组,我必须通过foreach将它们中的每一个插入DB,但是整个过程运行得太慢了 foreach($words as $word) { // even more checks if(strlen($word) < 3) continue; $word = $this->db->escapeString(strtolower($word)); // word not found? $result = $thi

我有一个问题,我得到了一个单词数组,我必须通过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}')");
}
这些桌子很轻

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秒。我可以将查询合并为一个查询吗?我错过什么了吗


谢谢。

此方法的前提是SQLite支持这种插入语法(这种语法在MySQL中有效):

在表(列)中插入值('value1')、('value2')、('value3')、('valueN')

您可以使用PHP使用
SELECT
语句中的逻辑构建SQL插入字符串,然后在最后执行两个查询;一个在单词表上,一个在搜索表上:

$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);
$sql_words='插入单词(word)值';
$sql_search='INSERT-INTO-search(reply,word)值';
$count=count($words);
$i=0;
$last_insert_id='';
$delim='';
foreach($words作为$word)
{
$result=$this->db->querySingle(“从word='{$word}'的单词中选择id);
如果($i<$count){
$delim=',';
}否则{
$delim='';
}
如果($结果){
$sql_search.=“({$result},{$word}”)”$delim;
}否则{
$sql_words.=“('{$word}')”$delim;
$sql_search.=“({$result},{$last_insert_id}”)”$delim;
}
$last\u insert\u id=$result;
$i++;
}
$this->db exec($sql\u单词);
$this->db->exec($sql\u search);

至于这段代码的有效性,我不确定,我有点困惑,
$id
来自哪里,并假设它与
$result

相同。此方法基于SQLite支持插入语法的前提(此语法在MySQL中工作):

在表(列)中插入值('value1')、('value2')、('value3')、('valueN')

您可以使用PHP使用
SELECT
语句中的逻辑构建SQL插入字符串,然后在最后执行两个查询;一个在单词表上,一个在搜索表上:

$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);
$sql_words='插入单词(word)值';
$sql_search='INSERT-INTO-search(reply,word)值';
$count=count($words);
$i=0;
$last_insert_id='';
$delim='';
foreach($words作为$word)
{
$result=$this->db->querySingle(“从word='{$word}'的单词中选择id);
如果($i<$count){
$delim=',';
}否则{
$delim='';
}
如果($结果){
$sql_search.=“({$result},{$word}”)”$delim;
}否则{
$sql_words.=“('{$word}')”$delim;
$sql_search.=“({$result},{$last_insert_id}”)”$delim;
}
$last\u insert\u id=$result;
$i++;
}
$this->db exec($sql\u单词);
$this->db->exec($sql\u search);

至于这段代码的有效性,我不确定,我有点困惑,
$id
来自哪里,并假设它与
$result

相同。此方法基于SQLite支持插入语法的前提(此语法在MySQL中工作):

在表(列)中插入值('value1')、('value2')、('value3')、('valueN')

您可以使用PHP使用
SELECT
语句中的逻辑构建SQL插入字符串,然后在最后执行两个查询;一个在单词表上,一个在搜索表上:

$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);
$sql_words='插入单词(word)值';
$sql_search='INSERT-INTO-search(reply,word)值';
$count=count($words);
$i=0;
$last_insert_id='';
$delim='';
foreach($words作为$word)
{
$result=$this->db->querySingle(“从word='{$word}'的单词中选择id);
如果($i<$count){
$delim=',';
}否则{
$delim='';
}
如果($结果){
$sql_search.=“({$result},{$word}”)”$delim;
}否则{
$sql_words.=“('{$word}')”$delim;
$sql_search.=“({$result},{$last_insert_id}”)”$delim;
}
$last\u insert\u id=$result;
$i++;
}
$this->db exec($sql\u单词);
$this->db->exec($sql\u search);

至于这段代码的有效性,我不确定,我有点困惑,
$id
来自哪里,并假设它与
$result

相同。此方法基于SQLite支持插入语法的前提(此语法在MySQL中工作):

在表(列)中插入值('value1')、('value2')、('value3')、('valueN')

您可以使用PHP使用
SELECT
语句中的逻辑构建SQL插入字符串,然后在最后执行两个查询;一个在单词表上,一个在搜索表上:

$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);
$sql_words='插入单词(word)值';
$sql_search='INSERT-INTO-search(reply,word)值';
$count=count($words);
$i=0;
$last_insert_id='';
$delim='';
foreach($words作为$word)
{
$result=$this->db->querySingle(“从word='{$word}'的单词中选择id);
如果($i<$count){
$delim=',';
}否则{
$delim='';
}
如果($结果){
$sql_search.=“({$result},{$word}”)”$delim;
}否则{
$sql_words.=“('{$word}')”$delim;
$sql_search.=“({$result},{$last_insert_id}”)”$delim;
}
$last\u insert\u id=$result;
$i++;
}
$this->db exec($sql\u单词);
$this->db->exec($sql\u search);

至于这个代码的有效性,我不确定,我有点困惑,
$id
来自何处,并假设它与
$result

相同,因此为了实现极快的性能,必须对一些内容进行更改。 首先是事务的使用(有点像mulquin的答案),其次我在words表中为列word添加了一个唯一的索引。这将帮助我跳过检查单词是否已存在的sql,而忽略该事务中的insert语句

这是将创建我的唯一ind的新表