Php 优化SQL查询
在一个非常简单的案例中,我遇到了一个有趣的问题。 我在MySQL数据库中有posts和users表。用户可以喜欢帖子。 因此,有一个单独的名为likes的表,它有列:Php 优化SQL查询,php,mysql,sql,query-optimization,Php,Mysql,Sql,Query Optimization,在一个非常简单的案例中,我遇到了一个有趣的问题。 我在MySQL数据库中有posts和users表。用户可以喜欢帖子。 因此,有一个单独的名为likes的表,它有列:user\u id,post\u id 当用户点击应用程序中的like按钮时,将执行对php脚本的请求。脚本正在检查表中是否有post_id和user_id与请求中的信息匹配的行。用户对一篇文章的喜欢不能超过1个,如果我在已经喜欢的文章上按“喜欢”,以前的“喜欢”应该会消失 我现在使用两个查询: 1) 选中“希望存在于表中” 2)
user\u id
,post\u id
当用户点击应用程序中的like按钮时,将执行对php脚本的请求。脚本正在检查表中是否有post_id和user_id与请求中的信息匹配的行。用户对一篇文章的喜欢不能超过1个,如果我在已经喜欢的文章上按“喜欢”,以前的“喜欢”应该会消失
我现在使用两个查询:
1) 选中“希望存在于表中”
2) 如果记录不存在-我将添加它,如果存在,我将删除它
现在我看到,在我的表中,同一个用户对同一篇文章有双重喜好。似乎来自单个用户的两个请求几乎可以立即执行
我如何优化它-所以它将不可能添加两个喜欢从用户的一个帖子?我认为我需要运行单个查询,但应该是什么?只需使用一个标志(值为0或1的列),并在不删除整行的情况下更新该值
您的步骤应如下所示:
在模板中,检查0或1的“不同”和“相似”很明显,插入/更新部件被多次激发。您应该调查发生这种情况的原因,然后尽可能防止这种情况发生 由于多次调用,DBMS被多次询问条目是否存在。所有电话的答案都是否定的。然后触发多个插入,得到重复的插入。因此,在SQL方面,有两件事出错了:
:
insert into likes (post_id, user_id, like_date)
values (@post_id, @user_id, current_date)
on duplicate key update like_date = current_date;
显然,您的插入/更新部件被触发了多次。您应该调查发生这种情况的原因,然后尽可能防止这种情况发生
由于多次调用,DBMS被多次询问条目是否存在。所有电话的答案都是否定的。然后触发多个插入,得到重复的插入。因此,在SQL方面,有两件事出错了:
为什么甚至可以为同一帖子和用户插入多条记录?应提供主键或唯一键,以实现此目的
我认为这对你的数据模型是必须的。
行动的顺序是错误的。一个可能的解决方案是先插入(一个会成功,另一个会失败——当然提供了上述密钥!),失败时会发布更新。然而,MySQL甚至可以在一个步骤中做到这一点:
使用重复键上的:
insert into likes (post_id, user_id, like_date)
values (@post_id, @user_id, current_date)
on duplicate key update like_date = current_date;
然后使用InnoDB
START TRANSACTION;
SELECT ... FOR UPDATE;
if it does not exist
INSERT ...;
else
DELETE ...
COMMIT;
通过使用事务语义,可以避免多个连接相互重叠的问题。我想我甚至避免了任何死锁的机会。那么就使用InnoDB吧
START TRANSACTION;
SELECT ... FOR UPDATE;
if it does not exist
INSERT ...;
else
DELETE ...
COMMIT;
通过使用事务语义,可以避免多个连接相互重叠的问题。我想我甚至避免了任何死锁的机会。如果需要更好的答案,您需要放置查询示例。它将帮助用户更好地了解您的问题。我认为您需要同步对PHP脚本的调用查看锁表,以避免同时更新。选择和更新前锁定表-一旦完成;如果需要更好的答案,您需要放置查询示例。它将帮助用户更好地了解您的问题。我认为您需要同步对PHP脚本的调用查看锁表,以避免同时更新。选择和更新前锁定表-一旦完成;解锁表无需“检查”任何内容。检查用于在前端模板中显示类似/不同图标无需“检查”任何内容。检查用于在前端模板中显示类似/不同图标