PHP定时导出用户Excel:优化MySQL查询避免重复数据
解决PHP+Cron定时导出特定时段新用户Excel的方案
首先必须明确:你的sys表必须添加一个记录用户注册时间的字段,这是实现精准时段筛选的基础——没有注册时间的话,根本无法区分用户是哪个时段注册的,也就没法满足你的需求。
第一步:添加注册时间字段
给sys表新增一个register_time字段,类型用DATETIME(如果需要更精确可以用TIMESTAMP,但DATETIME更直观),并且设置为非空。用户注册时,一定要把当前时间写入这个字段:
- 可以在MySQL层面用
NOW()自动填充,比如创建字段时设置默认值:ALTER TABLE sys ADD COLUMN register_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP; - 或者在PHP注册逻辑里,用
date('Y-m-d H:i:s')生成当前时间后插入数据库。
第二步:根据Cron执行时间编写动态查询逻辑
你的Cron是固定在每天6:00和16:00执行,所以我们只需要根据脚本执行的当前小时,计算对应的查询时间区间,确保两个时段的区间连续且无重叠:
逻辑规则
- 6:00执行时:导出前一天16:00 到 当日6:00的注册用户
- 16:00执行时:导出当日6:00 到 当日16:00的注册用户
实现方式(两种可选)
方式一:PHP计算时间区间,用预处理SQL查询
这种方式更灵活,适合需要在PHP里做额外时间处理的场景:
// 获取当前脚本执行的小时数 $currentHour = date('H'); $startTime = ''; $endTime = ''; if ($currentHour === '06') { // 6点执行:前一天16点到今天6点 $startTime = date('Y-m-d 16:00:00', strtotime('-1 day')); $endTime = date('Y-m-d 06:00:00'); } elseif ($currentHour === '16') { // 16点执行:今天6点到今天16点 $startTime = date('Y-m-d 06:00:00'); $endTime = date('Y-m-d 16:00:00'); } // 用mysqli预处理语句执行查询(避免SQL注入风险) $stmt = $conn->prepare("SELECT UID, Name, Number FROM sys WHERE register_time >= ? AND register_time < ?"); $stmt->bind_param("ss", $startTime, $endTime); $stmt->execute(); $result = $stmt->get_result();
方式二:直接用MySQL时间函数计算区间
如果不想在PHP里处理时间,可以直接在SQL里用MySQL的日期函数计算,代码更简洁:
$currentHour = date('H'); $sql = ''; if ($currentHour === '06') { $sql = "SELECT UID, Name, Number FROM sys WHERE register_time >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) + INTERVAL 16 HOUR AND register_time < CURDATE() + INTERVAL 6 HOUR"; } elseif ($currentHour === '16') { $sql = "SELECT UID, Name, Number FROM sys WHERE register_time >= CURDATE() + INTERVAL 6 HOUR AND register_time < CURDATE() + INTERVAL 16 HOUR"; } // 执行查询(同样建议用预处理,这里为简化展示直接执行) $result = $conn->query($sql);
第三步:确保数据无重复&优化
- 无重复保障:两个时间区间是完全连续且不重叠的(比如前一天16:00→当天6:00→当天16:00→次日6:00...),每个用户的注册时间只会落在一个区间里,所以不会出现重复导出的情况。
- 查询优化:给
register_time字段添加索引,避免数据量大时查询变慢:CREATE INDEX idx_sys_register_time ON sys(register_time); - 时间准确性:确保你的PHP服务器和MySQL服务器时间同步,避免因为时间差导致筛选错误;注册时优先用MySQL的
NOW()写入时间,比PHP的date()更可靠。 - Cron配置验证:确认Cron表达式是准确的,比如:
这个表达式确保脚本在每天6:00和16:00整执行,避免提前或延后导致的区间偏差。0 6 * * * /usr/bin/php /path/to/your/export_script.php 0 16 * * * /usr/bin/php /path/to/your/export_script.php
测试验证
可以手动修改几个用户的register_time来测试:
- userX的
register_time设为2024-05-20 15:00:00:16:00执行的脚本会导出他 - userY的
register_time设为2024-05-20 19:00:00:次日6:00执行的脚本会导出他 - userZ的
register_time设为2024-05-20 10:00:00:当日16:00执行的脚本会导出他
按照上面的步骤修改后,就能完全满足你的需求啦!
内容的提问来源于stack exchange,提问作者master Nixe
相关产品推荐
相关产品推荐

