我有一个mysql表,其中有“用户名”,“acctstarttime”和“acctstoptime”(和一个“id”)日期时间列。我需要获取具有相同用户名的其他“acctstarttime”和“acctstoptime”记录之间的acctstarttime或acctstoptime记录。例如,“John”有3条记录。
| 身份证|用户名|帐户开始时间|实际停止时间|
| - ------|- ------|- ------|- ------|
| 1个|约翰|二○二二年十二月二十九日|二○二三年一月一日|
| 第二章|约翰|二○二二年十二月三十日|二○二三年三月三日|
| 三个|约翰|二○二二年十二月十二日|二○二二年十二月十四日|
第二行acctstarttime在第一行acctstarttime和acctstoptime之间,第一行acctstoptime在第二行acctstarttime和acctstoptime之间。我想查询这2条记录。
我可以用php做,但是100万条记录大约需要3-4天或者更多。我的功能非常低效。
在mysql或php中我怎样才能减少这个时间(只是加速)?
我根据用户名将每个记录下载到不同的文件中。我写了这个laravel代码,但是它工作得太慢了。它可能会让人困惑。
function findRecordsBetweenSameHours()
{
$directory = storage_path() . "/app/";
$files = Storage::files('usernames');
foreach ($files as $file) {
$records =json_decode(file_get_contents($directory . $file), true);
foreach ($records as $record) {
$record["acctstarttime"] = Carbon::createFromFormat('Y-m-d H:i:s', $record["acctstarttime"]);
$record["acctstoptime"] = Carbon::createFromFormat('Y-m-d H:i:s', $record["acctstoptime"]);
foreach ($records as $record2) {
$record2["acctstarttime"] = Carbon::createFromFormat('Y-m-d H:i:s', $record2["acctstarttime"]);
$record2["acctstoptime"] = Carbon::createFromFormat('Y-m-d H:i:s', $record2["acctstoptime"]);
if (
($record2["acctstoptime"]->between($record["acctstarttime"], $record["acctstoptime"], false)
|| $record2["acctstarttime"]->between($record["acctstarttime"], $record["acctstoptime"], false)
)
&& $record2["acctsessionid"] != $record["acctsessionid"]
) {
Storage::append('x.log',
$record["acctsessionid"] . " - " . $record2["acctsessionid"] . " - " . $record["username"]
);
}
}
}
}
Storage::append('x.log',
"finish"
);
}
2条答案
按热度按时间yc0p9oo01#
您可以这样编写查询
du7egjpx2#
根据我对您问题的理解,您希望存在具有相同用户名和重叠时间段的另一个记录。
我推荐
exists
和一些不等式条件:对于每一行,子查询搜索同一用户的“重叠”记录,并筛选匹配的行。开始时间和结束时间的不等条件限定日期范围重叠。
(id, acctstarttime, acctstoptime)
上的索引可能有助于提高性能。