Php Mysqli num_行检查是否变慢? 我有一个C++程序,它把日志发送到我的服务器并把它存储在数据库上,问题是在插入一个新行之前检查重复数据是不起作用的,我认为程序发送的邮件非常快,而且在服务器之间没有延迟,所以MySQL不能处理这个问题,服务器客户端是否有任何解决方案?也许是锁行什么的 $date = date('Y-m-d', time()); $prep_select_qa = 'SELECT * from `logs` WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?'; $select_qa = $db->prepare($prep_select_qa); $select_qa->bind_param('sss', $_POST['guid'], $_POST['error_code'], $date); $select_qa->execute(); $select_qa->store_result(); $num_rows = $select_qa->num_rows; if($num_rows == 0) { $prep_insert_qa = 'INSERT INTO `logs` (`type`, `guid`, `sent_by`, `class_and_method`, `api_method`, `error_code`, `error_text`, `date_create`) VALUES (?,?,?,?,?,?,?,?)'; $insert_qa = $db->prepare($prep_insert_qa); $insert_qa->bind_param('ssssssss', $new, $_POST['guid'], $_POST['sentBy'], $_POST['classAndMethodName'], $_POST['APImethod'], $_POST['ErrorCode'], $_POST['ErrorText'], $date); $insert_qa->execute(); $insert_qa->store_result(); }

Php Mysqli num_行检查是否变慢? 我有一个C++程序,它把日志发送到我的服务器并把它存储在数据库上,问题是在插入一个新行之前检查重复数据是不起作用的,我认为程序发送的邮件非常快,而且在服务器之间没有延迟,所以MySQL不能处理这个问题,服务器客户端是否有任何解决方案?也许是锁行什么的 $date = date('Y-m-d', time()); $prep_select_qa = 'SELECT * from `logs` WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?'; $select_qa = $db->prepare($prep_select_qa); $select_qa->bind_param('sss', $_POST['guid'], $_POST['error_code'], $date); $select_qa->execute(); $select_qa->store_result(); $num_rows = $select_qa->num_rows; if($num_rows == 0) { $prep_insert_qa = 'INSERT INTO `logs` (`type`, `guid`, `sent_by`, `class_and_method`, `api_method`, `error_code`, `error_text`, `date_create`) VALUES (?,?,?,?,?,?,?,?)'; $insert_qa = $db->prepare($prep_insert_qa); $insert_qa->bind_param('ssssssss', $new, $_POST['guid'], $_POST['sentBy'], $_POST['classAndMethodName'], $_POST['APImethod'], $_POST['ErrorCode'], $_POST['ErrorText'], $date); $insert_qa->execute(); $insert_qa->store_result(); },php,mysql,database,mysqli,Php,Mysql,Database,Mysqli,首先,您的问题的答案是,您正在检索所有行以便对它们进行计数。这可能需要读取表中的所有数据并返回其中的一些数据(除非您有索引)。更快的方法是检查此查询返回的值: SELECT count(*) FROM `logs` WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?'; 更快速的方法不是计数,而是确定是否存在任何行: SELECT EXISTS (SELECT 1 FROM `logs`

首先,您的问题的答案是,您正在检索所有行以便对它们进行计数。这可能需要读取表中的所有数据并返回其中的一些数据(除非您有索引)。更快的方法是检查此查询返回的值:

SELECT count(*)
FROM `logs`
WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?';
更快速的方法不是计数,而是确定是否存在任何行:

SELECT EXISTS (SELECT 1
               FROM `logs`
               WHERE `guid` = ? AND `error_code` = ? AND `date_create` = ?'
              )
如果行存在,则返回1,否则返回0。在
guid、error\u code、date\u create
上有索引将使上述查询和原始查询都受益


在实践中,您应该遵循Marvin的建议并使用唯一的索引。这意味着数据库通过唯一索引而不是应用程序进行检查。一个非常重要的原因是比赛条件。如果两个用户同时插入同一行,两个用户都可能执行
If
语句,发现表中没有匹配的行,然后插入重复的行。

选择方案必须包含在BEGIN…COMMIT事务中,并具有FOR UPDATE。否则,其他连接可能会滑入并使您的支票失效

相反,请尝试在单个原子指令中执行此操作:

一旦你有了防止重复的索引

INSERT IGNORE——如果是dup,则不执行任何操作

在重复密钥更新时插入…允许您在尝试插入dup时更改某些内容


另外,插入解决方案将更快(这是您最初的问题)。

为什么不在
guid
error\u code
date\u create
上使用唯一约束,并让数据库处理重复的数据?我希望仅当日期不是相同的时候,才允许多行具有相同的guid和error\u代码same@user3519234 . . . 这就是为什么马文建议将日期放入索引中。@GordonLinoff所以我需要做这样的事情?ALTER TABLE logs添加唯一键
UNIQUE\u KEY
guid
error\u code
date\u created
)是。需要明确的是:我说的是一个约束覆盖所有三列,而不是每个列一个约束。