我有一个大型数据库,客户端存储个人消息和消息电子邮件通知[如果用户允许]。某些用户可以选择向他们的整个朋友网络发送消息。一些用户在他们的网络中有超过5000个朋友,所以如果他们选择整个网络,他们将向超过5000个朋友发送消息,系统将所有消息存储到一个表中。问题是,它不会插入超过1000条记录并忽略第一个1000之后的所有插入。我已经增加了数据包大小,bulk_insert_buffer_size但仍然没有运气。由于系统将一些信息存储在另一个表中以用于报告,因此每个插入都返回其新的消息ID。由于这个我不能使用“插入表(column1,column2)值(value1,value2),(value1,value2)....等。”
表引擎是innodb,mysql版本是5.1.3,托管在亚马逊网络服务上。我想要的是解决一次插入1000多条记录的问题。如前所述,它工作正常,但最多只能记录1000条记录,之后忽略所有记录。
我正在使用php foreach(){}为每个朋友插入消息,如果有电子邮件可用,请向用户发送通知。此foreach(){}还在另一个表[仅有3列]中插入相同的记录以生成报告。
答案 0 :(得分:1)
您是否尝试将查询拆分为更多子查询?也许在单个事务中(因为你使用InnoDB)?
我不确定亚马逊是否限制每个查询的插入次数,但只要它们不限制SQL查询的数量,您就可以执行更多INSERT
并且应该能够修复。
顺便问一下,您确定明文查询是否插入了所有5000个元素?可能是您的代码返回最多1000行的纯文本查询?您在LIMIT
查询中是否有任何SELECT
语句,我认为您在阅读数据时会执行这些语句?
答案 1 :(得分:0)
没有必要通过循环执行插入
您可以指定一个唯一的交易ID,如下所示
create sent_message
(
user_id int(10),
friend_id int(10),
batch_id int(10),
message text
);
/* user 1001 sent message to all his 5000 friends */
$timestamp = time();
insert into sent_message
select 1001, friend_id, $timestamp, friend_id, '$message'
from user_friend where user_id=1001;
/* email notification */
select email
from
user_profile
inner join sent_message
on user_profile.user_id=sent_message.friend_id
where
sent_message.uid=1001 and
batch_id=$timestamp and
user_profile.email!='';
/* loop the result and send the email notification
or to attach all the emails into an email alias,
then send via assigned email alias */