PHP& MySQL,快速连续多次检查行的有效方法吗?

时间:2016-06-05 00:39:36

标签: php mysql performance query-optimization

我面临着前所未有的挑战,无法找到有效的解决方案。 (可能是因为我不是一个训练有素的程序员而且不懂所有术语)。

挑战:

我有一个数据源,我每天都需要用它来维护一个mysql数据库。要做到这一点,需要检查是否存在记录,然后相应地更新或插入。

这本身很简单,但是为数千条记录运行它 - 对每条记录执行查询以检查它是否已存在于数据库中似乎效率很低。

是否有比循环浏览数据Feed和为每条记录运行单独查询更有效的方法?或许可以某种方式将它们准备成一个更大的查询(假设这是一种更有效的方法)。

我不确定此处是否需要代码示例,但如果有更多信息我可以提供,请稍等!我真的很感激任何建议。

编辑:

@Sgt AJ - 数据Feed中的每条记录都有许多不同的列,但它们都是通过ID索引的。我会在数据库中检查该ID以查看是否存在记录。在这种情况下,我只更新一个表,虽然是一个大表(30多列,主要是文本)。

2 个答案:

答案 0 :(得分:1)

问题是什么;

如果问题是检查,插入&更新;

insert into your_table
(email, country, reach_time)
values ('mike@gmail.com','Italy','2016-06-05 00:44:33')
on duplicate key update reach_time = '2016-06-05 00:44:33';

我认为,您的密钥是电子邮件

旧式,不要使用

如果电子邮件存在

update your_table set
reach_time = '2016-06-05 00:44:33'
where email = 'mike@gmail.com';

否则

insert into your_table
(email, country, reach_time)
values ('mike@gmail.com','Italy','2016-06-05 00:44:33')

答案 1 :(得分:0)

这取决于有多少'饲料'你必须加载的行。如果它像10那么按记录进行记录(如mustafayelmer所示)可能并不太糟糕。一旦你进入100及以上的区域,我强烈建议使用基于集合的方法。在创建和加载登台表时会有一些开销,但这可以(非常)快速地通过减少需要执行的查询和通过网络进行的往返次数来抵消。

简而言之,您要做的是:

-- create new, empty staging table
SELECT * INTO stagingTable FROM myTable WHERE 1 = 2

-- adding a PK to make JOIN later on easier
ALTER TABLE stagingTable ADD PRIMARY KEY (key1)

-- load the data either using INSERTS or using some other method
-- [...] 

-- update existing records
UPDATE myTable
   SET field1 = s.field1,
       field2 = s.field2,
       field3 = s.field3
  FROM stagingTable s
 WHERE s.key1 = myTable.key1

-- insert new records
INSERT myTable (key1, field1, field2, field3)
SELECT key1, field1, field2, field3
  FROM stagingTable new
 WHERE NOT EXISTS ( SELECT * 
                      FROM myTable old
                     WHERE old.key1 = new.key1 )

-- get rid of staging table again
DROP TABLE stagingTable

让您的数据更新。

注意:

  • 您可能想要创建stagingTable的名称' random'避免2'加载'并行运行并可能开始重复使用同一个表,给出各种奇怪的结果(和错误)。由于所有这些代码都已生成'无论如何,你可以在php中添加时间戳或其他东西到表名。

  • 在MSSQL上我会使用批量插入机制加载登台表中的所有数据。它可以使用bcpBULK INSERT; .Net实际上有SqlBulkCopy类。一些快速的谷歌搜索告诉我mysql有mysqlimport如果您不介意先写入临时文件然后从那里加载,或者您可以使用this来执行大的INSERT块而不是一个一个人。我一次避免做10k插入,而是每100或500左右做一次,你需要测试最有效率的插件。

PS:你需要在这里和那里调整我的语法,就像我说我更熟悉MSSQL的T-SQL方言。此外,您可以在登台表direclty上使用on duplicate key方法,从而将UPDATEINSERT组合在一个命令中。 [MSSQL为此使用MERGE,但它看起来完全不同,所以我不想在此处包含它。]

祝你好运。