Php MySQL检查大量数据
我有两个表名为Php MySQL检查大量数据,php,mysql,hash,Php,Mysql,Hash,我有两个表名为actual和check 表actual包含5000万行,每行包含32位哈希 表check包含1000万行,每行包含32位哈希 我必须验证check表中的哈希值是否在actual表中 我尝试了MySQL连接查询,就像 SELECT * FROM `check` LEFT JOIN `actual` on `check`.hash = `actual`.hash; 甚至在16GB内存的机器上,MySQL也崩溃了 我尝试使用PHP脚本,将附加字段添加到表c
actual
和check
表actual
包含5000万行,每行包含32位哈希
表check
包含1000万行,每行包含32位哈希
我必须验证check
表中的哈希值是否在actual
表中
我尝试了MySQL连接查询,就像
SELECT *
FROM `check`
LEFT
JOIN `actual`
on `check`.hash = `actual`.hash;
甚至在16GB内存的机器上,MySQL也崩溃了
我尝试使用PHP脚本,将附加字段添加到表check
中,作为字段名hash、status和found
Status&found默认为0,PHP将检查每个记录,并将Status更新为1,如果找到,则将found更新为1
有没有办法更快地检查数百万或记录
另一种方法是使用IGNORE插入惟一散列,并检查有多少未追加,但其过程很复杂
我正在使用的PHP代码非常简单,但速度非常慢
$sql = "SELECT * FROM `check` where status = 0 LIMIT 0, 1";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$check = "SELECT * FROM `actual` where hash = '".$row["hash"]."'";
$checkx = $conn->query($check);
$checky = "UPDATE `check` SET `status` = 1, `found` = 0 WHERE hash = '".$row["hash"]."'";
$conn->query($checky);
if ($checkx->num_rows > 0) {
$checky = "UPDATE `check` SET `status` = 1, `found` = 1 WHERE hash = '".$row["hash"]."'";
$conn->query($checky);
}
}
}
如果我没弄错,您只需要一个子查询:
UPDATE check SET status=1, found=1 WHERE hash IN (SELECT hash FROM actual)
我没有足够的数据来进行有意义的性能比较——试试看
编辑:
通过查看PHP解决方案,可以更清楚地了解需求,下面是一个更新的查询:
UPDATE `check` SET status=1, found=(hash IN (SELECT hash FROM actual)) WHERE status=0
注:
- 重要的是要索引
,否则搜索actual.hash
表将需要一段时间actual
- 根据
中选中行和未选中行之间的平衡,可能也值得为check
编制索引。如果大多数行未选中,则没有任何好处,但如果只有少数行未选中,则效果可能会很好。写入索引表可能要慢得多。你需要用你的数据集进行实验来找出答案check.status
UPDATE check SET status=1, found=1 WHERE hash IN (SELECT hash FROM actual)
我没有足够的数据来进行有意义的性能比较——试试看
编辑:
通过查看PHP解决方案,可以更清楚地了解需求,下面是一个更新的查询:
UPDATE `check` SET status=1, found=(hash IN (SELECT hash FROM actual)) WHERE status=0
注:
- 重要的是要索引
,否则搜索actual.hash
表将需要一段时间actual
- 根据
中选中行和未选中行之间的平衡,可能也值得为check
编制索引。如果大多数行未选中,则没有任何好处,但如果只有少数行未选中,则效果可能会很好。写入索引表可能要慢得多。你需要用你的数据集进行实验来找出答案check.status
也
- 什么版本的MySQL
- 请提供
。我们需要查看引擎、索引、数据类型等SHOW CREATE TABLE
显示“innodb\u buffer\u pool\u size”等变量代码>
一旦我们优化了查询,如果它仍然太慢,我将向您展示如何分阶段进行。这可能需要直接编写SQL,而不是通过Django。使用多表更新,而不是(选择…)中的
也
- 什么版本的MySQL
- 请提供
SHOW CREATE TABLE
。我们需要查看引擎、索引、数据类型等
显示“innodb\u buffer\u pool\u size”等变量代码>
你说的“撞车”是什么意思?重启?mysqld死了?或者仅仅是这个问题花了很长时间
一旦我们优化了查询,如果它仍然太慢,我将向您展示如何分阶段进行。这可能需要直接编写SQL,而不是通过Django。列是否有索引?@Raptor-是的。我们可以看到这两个表的SHOW CREATE TABLE语句,以及查询的解释吗?如果您在php中执行select以使用检索到的数据稍后更新记录,那么就不用麻烦了,直接使用update语句。@您的意思是不要对select和then update使用两个不同的语句吗?相反,您建议使用一条语句?列是否有索引?@Raptor-是的。我们可以看到这两个表的SHOW CREATE TABLE语句,以及查询的解释吗?如果您在php中执行select,以便稍后使用检索到的数据更新记录,那么不要麻烦,直接使用update语句。@您的意思是不要对select和then update使用两个不同的语句吗?相反,您建议使用一条语句?谢谢,我会尝试一下并告诉您。我更新了我的问题,您能告诉我如何执行类似于UPDATE check SET status=1,found=1的操作吗并且状态=0
Update found=1只有在找到匹配项时才会更新,否则状态=1仍将更新,以便我不检查重复项。谢谢,我将尝试此操作并让您知道。我更新了我的问题,您能否让我知道如何执行类似Update check SET status=1,found=1的操作(从实际值中选择哈希值)而status=0
Update found=1只有在找到匹配项时才会更新,否则status=1仍将更新,以便我不检查重复项。