如何选择PHPs大数组中没有ID的行?
我需要解决以下任务:我在PHP脚本中有一个相当大的ID数组,我需要从MySQL DB中选择所有ID不在该数组中的行 有几个类似的问题(),最喜欢的答案是使用如何选择PHPs大数组中没有ID的行?,php,mysql,arrays,Php,Mysql,Arrays,我需要解决以下任务:我在PHP脚本中有一个相当大的ID数组,我需要从MySQL DB中选择所有ID不在该数组中的行 有几个类似的问题(),最喜欢的答案是使用notin()construction和内爆(',',$array)在括号内 这起作用了。。。直到我的阵列达到2007ids和大约20kb(在我的例子中)之前,我都有一个“MySQL服务器已经消失”错误。据我所知,这是因为冗长的查询 对于这个问题也有一些解决方案,如下所示: SET GLOBAL max_allowed_packet=1073
notin()
construction和内爆(',',$array)
在括号内
这起作用了。。。直到我的阵列达到2007ids和大约20kb(在我的例子中)之前,我都有一个“MySQL服务器已经消失”错误。据我所知,这是因为冗长的查询
对于这个问题也有一些解决方案,如下所示:
SET GLOBAL max_allowed_packet=1073741824;
(刚刚摘自问题)
也许我可以这样做,但是现在我怀疑不在(内爆)
方法对于大型阵列是一个好方法(我希望在我的例子中,阵列可以高达8000个ID和100 kB)
对于大型阵列,有没有更好的解决方案
谢谢
编辑1
作为一种解决方案,建议将数组中的所有ID插入到临时表中,然后使用JOIN来解决初始任务。这是清楚的。然而,我从未使用过临时表,因此我还有一些额外的问题(可能值得作为一个单独的问题,但我决定将其留在这里):
如果我需要在一个MySQL会话中多次执行此例程,那么哪种方法更好:
哪个更好?或者我遗漏了什么?在这种情况下,通常最好创建一个临时表并对其执行查询。应该是这样的:
CREATE TEMPORARY TABLE t1 (a int);
INSERT INTO t1 VALUES (1),(2),(3);
SELECT * FROM yourtable
LEFT JOIN t1 on (yourtable.id=t1.a)
WHERE t1.a IS NULL;
当然,应该构造INSERT
语句,以便将数组中的所有值插入到临时表中
编辑:在一个
INSERT
语句中插入所有值很可能会导致您已经面临的相同问题。因此,我建议您在遍历PHP数组时,使用一个将被执行的插入到临时表中的语句。我曾经不得不解决这个问题,但在(id)WHERE子句中使用了大约20000-30000个标识符(索引
)
通过SELECT
query,我解决这个问题的方法是减少过滤标识符的数量,增加发送相同查询的次数,以便提取相同的数据
您可以为PHP使用array\u chunk
,并将20000
除以15
,这将为您提供15
单独的SQL调用,通过1500
标识符过滤记录(每次调用,您可以除以15
以进一步减少标识符的数量)。但是在您的例子中,如果您只需将2007
idenitifers除以10
,就会将每个SQL请求推送到数据库的标识符数量减少到200
,还有其他方法可以使用临时表来进一步优化它,等等
通过划分尝试筛选的索引数,它将加快每个查询的速度,比在单个转储中将每个索引发送到数据库的速度更快。在bd中创建另一个表,选择不在其中的id将数据加载到虚拟(索引)表中,然后使用外部索引JOIN@splash58我也想到了。考虑到阵列是动态的,可以吗?因此,我应该创建一些关于EDIT1的临时表(到目前为止从未使用过这个东西):这里有一些东西起作用。如果您的服务器没有内存限制,您可以保留临时表,直到会话终止。这样,如果需要重新执行查询,可以重新使用临时表中已有的数据。另一方面,如果确定不会对临时表运行任何查询,则可以删除它。这确实会对性能产生轻微影响,因为您的脚本将不得不等待表被删除,而不是在脚本完成后被删除。谢谢!如果我在一个查询中插入一个完整的表,我将面临同一个MySQL服务器消失的问题,这是正确的吗?是的,您可能会遇到同样的问题。出于这个原因,我建议您使用a并反复调用它。无论您使用PDO还是mysqli都不重要。如果需要,您可以使用事务。出于性能考虑,在每次执行准备好的语句时插入一个ID可以吗?可能可以,但我不知道您的其余查询和应用程序是如何工作的。