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

什么';检查MySQL表中是否已经存在URL的最快方法是什么?,mysql,mysqli,Mysql,Mysqli,我有一个varchar(255)列,将URL存储在MySQL数据库中。此列具有唯一索引 当我的爬虫程序遇到一个URL时,它必须检查数据库以查看该URL是否已经存在。如果存在,爬虫程序将选择有关该条目的数据。如果不存在,爬虫程序将添加url。我目前使用以下代码执行此操作: $sql = "SELECT id, junk FROM files WHERE url = '$url'"; $results = $this->mysqli->query( $sq

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

当我的爬虫程序遇到一个URL时,它必须检查数据库以查看该URL是否已经存在。如果存在,爬虫程序将选择有关该条目的数据。如果不存在,爬虫程序将添加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将如何以不同的方式处理这个问题,以及为什么它会更快?还有其他我应该测试的选择吗?我的爬虫程序正在做很多这样的检查,加快这个过程可能会大大提高我的系统的速度。

首先,URL将比
varchar(256)
长得多

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

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


至于实际的插入,另一种方法是对散列设置唯一约束。然后盲目地进行插入,允许SQL拒绝重复。(但您必须在代码中放入一个异常处理程序,它有自己的开销。)

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

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

我想不出一个“一行公用”可以同时选择和插入

我会先插入并检查是否成功(受影响的行),然后选择。如果您先检查,然后再进行插入,则可能存在在这个小时间窗口中插入url的可能性。而且,您需要添加更多的代码来处理这种情况。

您可以尝试设置一个准备好的语句来执行URL查询。cough hash cough(在这方面也有类似的问题;假设只需要严格的相等性测试)我已经读到,mysql在索引varchar时会搜索varchar的哈希。这列已经有索引了,所以我认为这是多余的。