检查MySQL表中是否已存在URL的最快方法是什么?

时间:2011-12-07 01:42:18

标签: mysql mysqli

我有一个varchar(255)列,我将URL存储在MySQL数据库中。此列具有唯一索引。

当我的抓取工具遇到网址时,必须检查数据库以查看该网址是否已存在。如果存在,则爬网程序选择有关该条目的数据。如果它不存在,则爬网程序会添加该URL。我目前使用以下代码执行此操作:

$sql = "SELECT id, junk
        FROM files
        WHERE url = '$url'";
$results = $this->mysqli->query( $sql );

// the file already exists in the system
if( $results->num_rows > 0 )
{
    // store data to variables
}

// the file does not exists yet... add it
else
{

    // insert new file
    $sql = "INSERT INTO files( url )
            VALUES( '$url' )";
    $results = $this->mysqli->query( $sql );

}

我意识到有很多方法可以做到这一点。我已经读过使用MySQL if / else语句可以加快速度。有人可以解释MySQL如何以不同的方式处理,以及为什么这可能会更快?我还应该测试其他替代方案吗?我的抓取工具正在进行大量的检查,加快这个过程可能会大大提高我的系统速度。

3 个答案:

答案 0 :(得分:1)

首先,网址要比varchar(256)长得多。

其次,因为他们长时间不想进行字符串比较,所以随着表的增长,它会变得非常慢。相反,创建一个带有哈希值的列并进行比较。

当然,您应该为哈希列编制索引。

对于实际插入,另一种方法是在哈希上放置一个唯一约束。然后盲目地进行插入,允许SQL拒绝欺骗。 (但是你必须在代码中加入一个异常处理程序,它有自己的开销。)

答案 1 :(得分:0)

考虑到不使用事务,如果WHERE条件不存在旧行,则插入新行,您可以使用:

"INSERT INTO files( url ) VALUES ( $url ) WHERE NOT EXISTS ( SELECT * FROM files WHERE url = $url );"

我无法想到同时选择和插入的“一线通用”。

答案 2 :(得分:0)

我会先插入并检查成功(affected_rows),然后选择。如果先检查,然后执行插入,则可能存在在该小时间窗口内插入URL的可能性。而且,您需要添加更多代码来处理这种情况。