PHP是检查行是否存在的最有效方法
考虑下表PHP是检查行是否存在的最有效方法,php,mysql,doctrine,Php,Mysql,Doctrine,考虑下表 +-------------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL
+-------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date | date | NO | | NULL | |
| sku | varchar(10) | | | NULL |
| impressions | int(11) | NO | | NULL | |
| sales | int(11) | NO | | NULL | |
+-------------+---------+------+-----+---------+----------------+
该表每天从前几天销售记录的批量下载中填充
每天下载的内容不仅包括前几天的销售数据,还包括过去90天的所有数据(可能有50k+记录)
但是,由于我们无法控制的事项,前几天的数据可能自原始插入后发生变化,例如:
第一天
Date: 2015-01-01
SKU: ABCD
Impressions: 100
Sales: 0
第二天
Date: 2015-01-01
SKU: ABCD
Impressions: 100
Sales: 3
Date: 2015-01-02
SKU: ABCD
Impressions: 105
Sales: 0
因此,对于数据下载中的任何给定记录,它可能是
a) 已看到且与以前相同-忽略
b) 新建-添加到数据库
c) 已看到但新数据-更新
可以说,这可以通过检查每一行来解决
while (!$file->eof()) {
$row = $file->fgets();
$data = explode("\t", $row);
$sku = $data[0];
$date = $data[1];
$impressions = $data[2];
$sales = $data[3];
$order = $em->getRepository('Orders')->findOneBy(['sku' => $sku, 'date' => $date]);
if($order && $order->getImpressions() != $impressions && $order->getSales() != $sales) {
$order->setImpressions($impressions);
$order->setSales($sales);
} else {
... create new model
}
$em->persist($order);
}
然而,具有更新数据的行将是最小的,并且对每一行进行选择意味着由于行的数量太多,这项工作将非常缓慢
所以我的问题是,什么样的模式可以用来尽可能有效地解决这个问题
欢迎任何想法我建议您用新下载的数据完全替换之前90天的数据。 理由很简单:
- 执行此操作的处理时间很短。50000行在数据库中很小。我可能会这样做,即使它是一百万行李>
- 尝试仅替换更改的行很复杂,可能会导致错误。
日期
和库存单位
(组合),销售和印象是可以更新的字段。如果这是正确的,那么在MySQL中最有效的方法就是使用INSERT。。。在重复密钥更新时…
查询:
date
和sku
列上创建唯一键- 请查看有关此语法的详细信息
- 如果第二天包含前一日期记录的数据更新是补充,您可以执行
,但我认为您的情况并非如此sales=sales+VALUES(sales)
INSERT INTO
mytable (`date`, sku, impressions, sales)
VALUES
('2015-01-01', 'ABCD', 100, 3),
('2015-01-02','ABCD', 100, 3),
...
ON DUPLICATE KEY UPDATE
impressions = VALUES(impressions),
sales = VALUES(sales)