【发布时间】:2012-01-08 20:33:27
【问题描述】:
我想修剪 MySQL 数据库中的所有重复条目,只留下最早或最新的一个,具体取决于 $keep 是什么。我正在使用以下内容,但速度很慢:
function pruneDuplicates($keep) {
if($keep == 1)
$order = "ASC";
else if ($keep == 0)
$order = "DESC";
//Go through and find the duplicate hashes. Grab the IDs that correspond to them then delete all but one ID
$query = "SELECT HEX(hash) FROM hashes GROUP BY hash HAVING count(hash) > 1";
$result = mysql_query($query) or die("ERROR: ".mysql_error());
while ($row = mysql_fetch_array($result)) {
$query = "SELECT id from hashes WHERE hash = UNHEX('$row[0]') ORDER BY id $order LIMIT 1";
$innerResult = mysql_query($query) or die("ERROR: ".mysql_error());
$innerRow = mysql_fetch_array($innerResult);
$query = "DELETE FROM hashes WHERE hash = UNHEX('$row[0]') AND id != $innerRow[0]";
echo $query."<br>";
mysql_query($query) or die("ERROR: ".mysql_error());
}
echo "Prune successful...";
}
echo $query 用于调试。该脚本需要几分钟才能运行。它修剪了大约 80,000 条记录(我有超过 100,000 条记录,但预计会有 1,000,000 条以上)。我在看 mysqladmin proc stat,发现删除需要时间。
我的表说明如下:
+-----------+------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date | timestamp | NO | | CURRENT_TIMESTAMP | |
| hash | binary(16) | NO | MUL | NULL | |
哈希是一个索引。
【问题讨论】:
-
我怀疑您可以使用单个
DELETE查询,其中显示DELETE everything with hash = 'hashtodelete' AND id != 'onetokeep'。请注意,这是伪代码。循环这样做会很慢。 -
这基本上就是我正在做的事情,但是我必须找到要删除的散列,因此上面的 select 语句。查找重复的哈希...对于每个哈希获取第一个或最后一个 ID->DELETE WHERE id != id 和 hash = hashtodelete...重复
-
啊,我明白了。好吧,如果您从第一个获得
hash和id值,我认为您可以消除第二个SELECT。您可以为IN()构建一个字符串,然后将id与您不想删除的ids 放在NOT (IN ...)中。
标签: php mysql optimization