我有PHP脚本,每5分钟运行一次,从API获取数据,然后将其写入MySQL表。我的网站的用户(300+)可以通过数据表查询该数据,其他页面显示一些数据。 然后PHP脚本获取API数据
foreach($array as $row)
{
$query .= "INSERT INTO table_name
(
col_name1,
col_name2,
col_name3,
col_name4,
col_name5
)
VALUES
(
'".$row["value1"]."',
'".$row["value2"]."',
'".$row["value3"]."',
'".$row["value4"]."',
'".$row["value5"]."'
);";
}
mysqli_query($connect, "DELETE FROM table_name");
mysqli_multi_query($connect, $query);
每次脚本运行时,DELETE然后INSERT到该空表中。 该表有1000行,这将随着时间的推移而增长。 我收到的报告显示数据表有时是空的,在出现任何内容之前,他们必须刷新几次。
是否有更好的方法来构建数据库,表和/或查询。
答案 0 :(得分:1)
为每一行运行单独的插入语句会非常缓慢。
运行多插入,使用单个语句插入多行会更有效。例如,使用单个语句插入四行。
INSERT INTO t (a,b,c) VALUES (?,?,?) ,(?,?,?) ,(?,?,?) ,(?,?,?)
一个潜在的缺点是,如果一行由于错误而无法插入,则整个语句将被回滚,并且没有任何行被插入。
SQL语句的最大长度受max_allowed_packet
限制。没有必要在单个语句中插入所有行。在pop中插入10行会显着减少语句执行次数。
假设该表使用InnoDB存储引擎...
如果我们禁用自动提交,并在单个事务的上下文中运行DELETE
语句和INSERT
语句,那么该表将不会好像是空的"到其他会议。其他会话将继续在DELETE
之前看到表格的内容......直到COMMIT
完成。
代码模式似乎容易受到SQL注入攻击。 (尤其是使用多查询时会产生很多肮脏的东西。
减轻SQL注入的最佳做法是使用带有绑定占位符的预准备语句。
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
修改强>
作为替代方法,如果表具有主键或唯一键,请考虑
加载临时表(不是目标表)。
然后运行语句以应用更改以使目标表与临时表同步。我们将通过名称来源引用临时表。
- 更新现有行
UPDATE target t
JOIN source s
ON s.id = t.id
SET t.col = s.col
, t.foo = s.foo
, t.bar = s.bar
- 插入新行
INSERT INTO target
SELECT s.*
FROM ( SELECT r.*
FROM source r
-- anti-join
LEFT
JOIN target q
ON q.id = r.id
WHERE q.id IS NULL
) s
- 删除已删除的行
DELETE t.*
FROM target t
-- anti-join
LEFT
JOIN source s
ON s.id = t.id
WHERE s.id IS NULL
这样可以避免空白"目标表,因此并发SELECT语句仍将返回行,而目标表正在"同步' d"。
针对目标表的DML UPDATE / INSERT / DELETE操作可以在单个事务的上下文中执行。