我有一个laravel命令,它搜索SQL Server数据库中的数据,并在MySQL数据库中插入每一行(如果已经存在,则更新)。
这是当前工作的代码:
首先,从SQL服务器搜索行:
$etiquetas = DB::connection('delisur_picking')
->table('deli_eti_correl')
->where('correl', '>', $lastLabel)
->orderBy('correl', 'asc')
->get()
->chunk(100);
然后插入和/或更新:
$i = 0;
$numins=0;
$numupd=0;
$tot=0;
$locations=DB::connection("mysql")->table("locations")->select("id", "code")->get();
$alocations=array();
foreach($locations as $l){
$alocations[$l->id]=$l->code;
}
foreach ($etiquetas as $chunk) {
$i = $i + 1;
Log::info('Cargando '.$i.' chunks de '.count($etiquetas));
$arrlabelI=array();
$arrlabelU=array();
foreach ($chunk as $etiqueta) {
$tot++;
$label=array();
$labelExists=DB::connection("mysql")->table("labels")->where("correlative", $etiqueta->correl)->exists();
$locationid=array_search($etiqueta->origen, $alocations);
$label["cod_prod"]=$etiqueta->cod_prod;
$label["nom_prod1"]=trim($etiqueta->nom_prod1);
$label["nom_prod2"]=trim($etiqueta->nom_prod2);
$label["q_caja"]=$etiqueta->q_caja;
$label["fec_elab"]= $etiqueta->fec_elab;
$label["lote"]= $etiqueta->lote;
$label["fec_sys"]= $etiqueta->fec_sys;
$label["actual_location"]= trim($etiqueta->origen) == '' ? null : ($locationid!==false ? $locationid : null);
if($labelExists){
$arrlabelU[$etiqueta->correl]=$label;
Log::info("Correlativo marcado para actualizacion: $etiqueta->correl");
}else{
$label["correlative"]=$etiqueta->correl;
$arrlabelI[]=$label;
Log::info("Correlativo marcado para insercion: $etiqueta->correl");
}
}
DB::connection('mysql')->table("labels_alt")->insert($arrlabelI);
$numins+=count($arrlabelI);
foreach($arrlabelU as $idx => $row){
DB::connection('mysql')->table("labels")->where("correlative", $idx)->update($row);
$numupd++;
}
}
标签表定义如下:
CREATE TABLE `labels` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`correlative` BIGINT(20) NULL DEFAULT NULL,
`cod_prod` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`nom_prod1` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`nom_prod2` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`q_caja` BIGINT(20) NULL DEFAULT NULL,
`fec_elab` DATETIME NULL DEFAULT NULL,
`lote` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`fec_sys` DATETIME NULL DEFAULT NULL,
`actual_location` VARCHAR(191) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
)
对于每个块,填充数组$alabelsI
和$alabelsU
(给定每个块的行数,大约总共50秒)需要1/2秒,插入数据需要半秒$alabelsI
问题:
uprett
函数。如果我不能使用uprett
,是否有比上面的代码更优化的方法来插入或更新数据?提前谢谢
解决了的
我们找到的完成所需任务的最快形式是:
foreach ($etiquetas as $chunk) {
$i = $i + 1;
Log::info('Cargando '.$i.' chunks de '.count($etiquetas));
$arrlabelI=array();
foreach ($chunk as $etiqueta) {
$tot++;
$label=array();
$locationid=array_search($etiqueta->origen, $alocations);
$label["cod_prod"]=iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->cod_prod);
$label["nom_prod1"]=iconv('Windows-1252', 'UTF-8//TRANSLIT', trim(iconv('Windows-1252', 'UTF-8//TRANSLIT', "$etiqueta->nom_prod1")));
$label["nom_prod2"]=iconv('Windows-1252', 'UTF-8//TRANSLIT', trim(iconv('Windows-1252', 'UTF-8//TRANSLIT', "$etiqueta->nom_prod2")));
$label["q_caja"]=iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->q_caja);
$label["fec_elab"]= iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->fec_elab);
$label["lote"]= iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->lote);
$label["fec_sys"]= iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->fec_sys);
$label["actual_location"]= trim($etiqueta->origen) == '' ? null : ($locationid!==false ? $locationid : null);
$label["correlative"]= iconv('Windows-1252', 'UTF-8//TRANSLIT', $etiqueta->correl);
$arrlabelI[]=$label;
}
DB::connection('mysql')->table("labels_alt")->insert($arrlabelI);
$numins+=count($arrlabelI);
}
$pstmt=DB::connection("mysql")->getPDO()->prepare("call insertLabels()");
$pstmt->execute();
CREATE DEFINER=`root`@`localhost` PROCEDURE `insertLabels`()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE icorrelative, qcaja BIGINT(20);
DECLARE codprod, nomprod1, nomprod2, ilote VARCHAR(191);
DECLARE fecelab, fecsys DATETIME;
DECLARE createdat, updatedat TIMESTAMP;
DECLARE done INT DEFAULT FALSE;
DECLARE ext_cursor CURSOR FOR
SELECT labels_alt.correlative, labels_alt.q_caja, labels_alt.cod_prod, labels_alt.nom_prod1, labels_alt.nom_prod2, labels_alt.lote, labels_alt.fec_elab, labels_alt.fec_sys, labels_alt.created_at
FROM labels_alt INNER JOIN labels ON labels_alt.correlative=labels.correlative;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
INSERT INTO labels (correlative, q_caja, cod_prod, nom_prod1, nom_prod2, lote, fec_elab, fec_sys, created_at, updated_at) SELECT correlative, q_caja, cod_prod, nom_prod1, nom_prod2, lote, fec_elab, fec_sys, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP FROM labels_alt a NATURAL LEFT JOIN labels b WHERE b.correlative IS NULL;
OPEN ext_cursor;
read_loop: LOOP
FETCH ext_cursor INTO icorrelative, qcaja, codprod, nomprod1, nomprod2, ilote, fecelab, fecsys, createdat;
IF done THEN
LEAVE read_loop;
END IF;
UPDATE labels SET q_caja=qcaja, cod_prod=codprod, nom_prod1=nomprod1, lote=ilote, fec_elab=fecelab, fec_sys=fecsys, created_at=createdat, updated_at=CURRENT_TIMESTAMP WHERE correlative=icorrelative;
END LOOP;
CLOSE ext_cursor;
TRUNCATE labels_alt;
END
简而言之,就是通过将所述语句移动到存储过程中,尽可能减少来自Laravel的SQL语句的执行。
JavaFX一次更新大量按钮/节点的最佳方法是什么? 我提前道歉,这是我的第一个问题堆栈溢出... 因此,我为我们创建的特定内部设备创建了一个模拟器。该设备上有一个按钮,以100ms的速率以LED闪烁。 所以我基本上创建了一个看起来像内部设备的视图。我在视图上设置了一个通过
事实上中的变量比变量慢,这是众所周知的,并且已经在本网站的不同问题中讨论过了。然而,我仍然没有找到答案的一件事是,使用代码中不同函数内部使用的全局变量(如常量)的最佳和最快的方法是什么? 到目前为止,我能找到的最佳解决方案是定义一个函数,在这里我将全局变量分配给局部变量。 输出: 但这是一个丑陋的解决方案,而且比使用局部变量还要慢。在函数内部使用全局/常量变量等效的最著名的方法是什么,而不必将它们
问题内容: 我需要从每日CSV文件中消耗大量数据。CSV包含约12万条记录。使用hibernate模式时,这会减慢爬行速度。基本上,当使用saveOrUpdate()时,hibernate似乎在每个单独的INSERT(或UPDATE)之前执行SELECT。对于使用saveOrUpdate()持久存储的每个实例,在实际的INSERT或UPDATE之前发出SELECT。我能理解为什么要这样做,但是在进
我正在写一个数据挖掘程序,可以批量插入用户数据。 当前SQL只是一个普通的批量插入: 如果发生冲突,如何进行更新?我试过: 但它抛出
请让我知道,如何使用带注释的映射器在mybatis中执行批插入/更新。
问题内容: 我正在建立一个通过各种CSV提要更新大量数据的系统。通常,我只会遍历提要中的每一行,进行选择查询以检查该项目是否已经存在,并根据是否存在来插入/更新该项目。 我觉得这种方法扩展性不强,可能会在较大的提要上重击服务器。我的解决方案是像往常一样遍历所有项目,但将它们存储在内存中。然后,对于每100个左右的项目,对这100个项目进行选择,并获取数据库中匹配的现有项目的列表。然后将插入/更新语