Php Phalcon查询超慢大循环内
我用的是Phalcon 3.0.4。我对文件夹中的每个文件都做了一个foreach。目前我只有4000个文件。我做了一个findFirst来检查MySQL中是否已经存在文件名。我的表中有100000行。但是当我使用findFirst时,响应非常慢,我必须等待20分钟才能得到响应。这是我的密码:Php Phalcon查询超慢大循环内,php,mysql,query-optimization,phalcon,Php,Mysql,Query Optimization,Phalcon,我用的是Phalcon 3.0.4。我对文件夹中的每个文件都做了一个foreach。目前我只有4000个文件。我做了一个findFirst来检查MySQL中是否已经存在文件名。我的表中有100000行。但是当我使用findFirst时,响应非常慢,我必须等待20分钟才能得到响应。这是我的密码: $dir = new FilesystemIterator("files/path/to/my/files/"); foreach ($dir as $file) { if ($file-&
$dir = new FilesystemIterator("files/path/to/my/files/");
foreach ($dir as $file) {
if ($file->getExtension() == 'json') {
$filename = $file->getFilename();
$explode_filename = explode("_", $filename);
$date = $explode_filename[0];
$unformatted_date = DateTime::createFromFormat("Ymd-His", $date);
$date_server = $unformatted_date->format("Y-m-d H:i:s");
$timestamp_app = $explode_filename[2];
$date_app = date("Y-m-d H:i:s", $timestamp_app/1000);
echo $date_server;
$json_data = json_decode(file_get_contents($file), true);
$scan = Scans::findFirst(array(
"name = :name:",
"bind" => array("name" => $filename)
));
if (!$scan) {
...
}
}
}
我尝试使用QueryBuilder PHQL进行查询,但结果相同:
$scan = $this->modelsManager->createBuilder()
->from("Scans")
->where("name = :name:", ["name" => $filename])
->limit(1)
->getQuery()
->execute();
如果删除findFirst或queryBuilder,响应时间约为30毫秒,但使用findFirst则需要约20分钟。。。如何提高我的表中搜索的性能?通过将代码更改为性能更好的代码:
$dir = new FilesystemIterator("files/path/to/my/files/");
$fileNames = [];
foreach ($dir as $file) {
if ($file->getExtension() == 'json') {
$filename = $file->getFilename();
$explode_filename = explode("_", $filename);
$date = $explode_filename[0];
$unformatted_date = DateTime::createFromFormat("Ymd-His", $date);
$date_server = $unformatted_date->format("Y-m-d H:i:s");
$timestamp_app = $explode_filename[2];
$date_app = date("Y-m-d H:i:s", $timestamp_app/1000);
echo $date_server;
$json_data = json_decode(file_get_contents($file), true);
// save the above data to some arrays
$fileNames[] = $fileName;
}
}
$scans = Scans::find([
'columns' => 'check only columns you need, otherwise you will have full models with hydration',
'conditions' => 'name IN ({fileNames:array})',
'group' => 'name',
'bind' => [
'fileNames' => $fileNames
]
]);
foreach($fileNames as $fileName) {
$filteredScans = $scans->filter(function($scan) use ($fileName) {
return $scan->name == $fileName;
}
if(!$filteredScans) {
// do here whatever
}
}
这个解决方案可能会占用大量内存,然后您可以在这里包含一些分页,比如执行一些限制,比如适当的for,以及一次执行100-10000行,具体取决于您有多少RAM
在Scans.name上创建索引
如果不是uniq,请使用group by Scans.name
设置一些列,然后使用它们
也许在“名称”列上添加索引会给您带来性能提升哦,是的,您说得对,非常好的建议!在“我的名字”字段上设置一个索引效果很好,你的解决方案也很好。当然,索引是必要的:如果你使用mysql,那么切换到mariadb 10.1,我的解决方案的内存会更大——如果你能腾出更多的内存,那么它肯定会比在循环中选择一行更快。但是如果你的解决方案是这样的话,我就无法确定条件了!扫描,然后我做一些事情,但你们不需要在这里做,你们正在寻找扫描的名称是一个文件名,若并没有这样的行和这样的文件名,它将不会从数据库返回,所以这个检查是不需要的。哦,等等,你在那儿$扫描,然后将其更改为NOT IN。如果文件名在我的表中不存在,我需要添加json文件数据