检查MySQL中不存在的大型数组元素的最快方法

时间:2016-08-04 17:59:46

标签: php mysql arrays

我需要检查MySQL表中不存在数组的哪些元素。 我正在进行个别查询,但它正在炸毁我的MySQL。

4 个答案:

答案 0 :(得分:2)

如果有大量值,请将它们加载到临时表中并将其加入左侧。

  $sql =  "select t.* from temptable t left join foo f on f.id = t.id where f.id is null";

答案 1 :(得分:2)

关于这个帖子的几个答案和评论误解了OP要求的内容。 OP没有要求MySQL表中没有PHP数组中的值。 OP要求相反:PHP数组中的值不存在于MySQL表中。

将值加载到临时表中。我假设一个包含整数的变量INPUT。这是一次插入多行的代码。如果这将生成长于$array的INSERT语句,则批量加载数组。

max_allowed_packet

对您正在搜索的表格进行外部联接。如果没有匹配,则该值不存在。

$pdo->query("CREATE TEMPORARY TABLE values_to_search (value INT PRIMARY KEY)");

$sql = "INSERT INTO values_to_search (value) VALUES " 
    . implode(",", array_fill(1, count($array), "(?)"));
$stmt = $pdo->prepare($sql);
$stmt->execute($array);

答案 2 :(得分:0)

您可以结合使用array_diff()select distinct ...来快速获得所需的结果:

$array = [1,2,3,4,5,6,7,8,9,0];
$mysql_array = [];
// $mysql_array = [3,7,9]; // uncomment this if you wish to test without DB data

$sql = 'select distinct id as id from mysql_table';

// mysql querying functions or PDO or whatever

while(looping results)
{
    $mysql_array[] = $row['id'];
}

print_r(array_diff($array, $mysql_array));

// If using $mysql_array = [3,7,9]; test data then you will get this result
/*
Array
(
    [0] => 1
    [1] => 2
    [3] => 4
    [4] => 5
    [5] => 6
    [7] => 8
    [9] => 0
)
*/

重要提示:

如果distinct查询返回一百万条或更多记录,上面列出的方法可能会耗尽PHP脚本可用的可用内存。

答案 3 :(得分:0)

我建议另一种解决方案,基于OP的上下文意味着所有已经注册的值将被探索。
编辑:查看@MonkeyZeus的回答我发现他们可能会多次注册,所以我在下面的查询中添加了DISTINCT

可能会更快,因为它只使用一个简单的查询...但不确定,因为它也会迭代一个巨大的数组 另一方面,它不会导致内存问题,因为只使用了fetch(),而不是fetchAll()

假设value是涉及列的名称,$searched_values是包含搜索值的(简单)数组:

// make known values and searched values sorted the same
$stmt = $pdo->query('SELECT DISTINCT value FROM mytable ORDER BY value');
sort($searched_values);

$unknown_values = [];
$known_value = NULL;

foreach ($searched_values as $searched_value) {
    if (!$known_value) {
        // previous known_value already consumed (or end), try to get next one 
        $known_value = $stmt->fetch()['value'];
    }
    if ($known_value == $searched_value) {
        // consume current known_value
        $known_value = NULL;
    } else {
        // otherwise current $searched_value is unknown, register it:
        $unknown[] = $searched_value;
    }
}