我必须在我的数据库中注册数百万的页面浏览量,我正在寻找减少服务器负载的最佳解决方案。

1.实际解决方案:检查是否唯一并在“原始”表和“优化”表中注册

// script
$checkUnique = mysqli_query( $con, "SELECT FROM rawTable
         WHERE datatime = '$today' AND ip = '$ip'
         ORDER BY datetime DESC LIMIT 1" );
mysqli_query( $con, "INSERT INTO rawTable ( id, datetime, url, ip, ua )
         VALUES ( NULL, '$now', '$url', '$ip', '$ua' )" );
if( mysqli_num_rows( $checkUnique ) == 0 ) {
    mysqli_query( $con, "INSERT INTO optimizedTable ( id, day, total )
                         VALUES ( NULL, '$today', 1 )" ); }
else{
    mysqli_query( $con, "UPDATE optimizedTable SET total = total + 1
            WHERE day = '$today' ORDER BY day DESC LIMIT 1"; }

2. 仅在“原始”表中注册 View ,然后使用 cronjob 填充“优化”表
// script
mysqli_query( $con, "INSERT INTO rawTable ( id, datetime, url, ip, ua, alreadyOptimized )
         VALUES ( NULL, '$now', '$url', '$ip', '$ua', 0 )" );

// cronjob -> check if is unique, populate mysql tables +
//         change column alreadyOptimized from 0 to 1 in raw table

3. 在 txt 或 csv 文件中注册原始 View ,然后使用 cronjob 填充 mysql 表
// script
$file = fopen("file.txt", "w");
fwrite($file, "$now,$url,$ip,$ua\n");

// cronjob -> check if is unique, populate mysql tables + delete rows from txt/csv file

最好(最轻、最快)的方法是什么?有没有更好的解决方案?

PS:服务器负载是由select查询来检查 View 是否唯一引起的

最佳答案

手动选择检查记录是否存在是您可以做的最糟糕的事情 - 它可以(并且将会)产生错误的结果。 MySQL 与连接到它的任何进程之间存在时间滞后。唯一正确的方法是放置 UNIQUE 约束,而只是 INSERT 。这是 100% 确定您的数据库不包含重复项的唯一方法。

这对您的用例很有趣的原因是它将您的代码减少了 50%。你不必先 SELECT,因此你摆脱了一个巨大的瓶颈。

如果需要更新现有记录,请使用 INSERT IGNOREINSERT INTO .. ON DUPLICATE KEY UPDATE

您的唯一约束将是 datetime, ip 列上的复合索引。为了进一步优化这一点,您可以在表中创建一个 binary(20) 列,并让它包含 sha1 组合的 datetime, ip 哈希。使用触发器,您可以在插入之前创建哈希,使整个过程对实际插入表的人不可见。

如果插入失败,则记录存在。如果插入成功,您就完成了您想做的事情。没有使用 SELECT 应该会产生性能。之后,如果它仍然很慢 - 这只是您使用的服务器的 I/O 限制,您需要在硬件级别上寻找优化。

关于PHP在MYSQL中注册数百万条记录的最快方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35359492/

10-11 19:52