我有一个这样的查询,应该在每个MySQL操作之后执行。此查询现在正在减慢页面加载速度,因为数据增加了,我做了所有事情,如正确的索引,但查询仍然相对较慢。
还有其他方法可以执行这些检查吗?
$query = "
UPDATE {$tprefix}wh_profg
SET status =
CASE
WHEN
batchno in (
select
batchno
from
{$tprefix}wh_profulldetail
where
remainingdays <= 0
)
THEN
'expired'
WHEN
QC = 'rejected' and QA != 'rejected'
and status != 'expired'
THEN
'QC-rejected'
WHEN
QA = 'rejected' and QC != 'rejected'
and status != 'expired'
THEN
'QA-rejected'
WHEN
QA = 'rejected' and QC = 'rejected'
and status != 'expired'
THEN
'QA&QC-rejected'
WHEN
(
batchno in (
select
batchno
from
{$tprefix}wh_profulldetail
where
available <= 0
)
) and status != 'expired'
and status NOT LIKE '%rejected'
THEN
'empty'
WHEN
QC ='quarantine' and status != 'empty'
and status != 'expired' and
batchno in (
select
batchno
from
{$tprefix}wh_profulldetail
where
available > 0 and remainingdays > 0
)
THEN
'quarantine'
WHEN
QC ='approved' and QA = 'approved'
and status != 'empty' and status != 'expired'
and status NOT LIKE '%rejected' and
batchno in (
select
batchno
from
{$tprefix}wh_profulldetail
where
available > 0 and remainingdays > 0
)
THEN
'available'
ELSE
'unknown'
END
";
答案 0 :(得分:3)
从澄清中,我认为你说wh_profulldetail是一个加入wh_profg和wh_profg_usage的视图。对wh_profg_usage的任何插入或更新都可能影响wh_profg.status。因此,您需要在wh_profg和wh_profg_usage上使用INSERT和UPDATE触发器。
创建触发器后,删除原始UPDATE查询。更新将在需要时由触发器执行。此外,更新将仅在受影响的一个wh_profg行上执行。这应该可以消除您的性能问题,因为您当前的更新查询正在更新wh_profg中的每一行。
触发器看起来像:
DELIMITER //
CREATE TRIGGER insert_wh_profg_usage AFTER INSERT ON wh_profg_usage
FOR EACH ROW
UPDATE wh_profg a SET status = status WHERE batchno = NEW.batchno;
//
CREATE TRIGGER update_wh_profg_usage AFTER UPDATE ON wh_profg_usage
FOR EACH ROW
UPDATE wh_profg a SET status = status WHERE batchno = NEW.batchno;
//
CREATE TRIGGER update_wh_profg_usage AFTER DELETE ON wh_profg_usage
FOR EACH ROW
UPDATE wh_profg a SET status = status WHERE batchno = NEW.batchno;
//
CREATE TRIGGER insert_wh_profg BEFORE INSERT ON wh_profg
FOR EACH ROW
BEGIN
SELECT 1
,remainingdays
,available
INTO @detailfound
,@remainingdays
,@available
FROM wh_profulldetail
WHERE batchno = NEW.batchno;
IF @remainingdays <= 0
THEN SET NEW.status = 'expired';
ELSEIF NEW.qc = 'rejected'
AND NEW.qa != 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QC-rejected';
ELSEIF NEW.qa = 'rejected'
AND NEW.qc != 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QA-rejected';
ELSEIF NEW.qa = 'rejected'
AND NEW.qc = 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QA&QC-rejected';
ELSEIF NEW.status != 'expired'
AND NEW.status NOT LIKE '%rejected'
AND @detailfound = 1
AND @remainingdays <= 0
THEN SET NEW.status = 'empty';
ELSEIF NEW.qc ='quarantine'
AND NEW.status != 'empty'
AND NEW.status != 'expired'
AND @detailfound = 1
AND @available > 0
AND @remainingdays > 0
THEN SET NEW.status = 'quarantine';
ELSEIF NEW.qc = 'approved'
AND NEW.qa = 'approved'
AND NEW.status != 'empty'
AND NEW.status != 'expired'
AND NEW.status NOT LIKE '%rejected'
AND @detailfound = 1
AND @available > 0
AND @remainingdays > 0
THEN SET NEW.status = 'available';
ELSE SET NEW.status = 'unknown';
END IF;
END;
//
CREATE TRIGGER update_wh_profg BEFORE UPDATE ON wh_profg
FOR EACH ROW
BEGIN
SELECT 1
,remainingdays
,available
INTO @detailfound
,@remainingdays
,@available
FROM wh_profulldetail
WHERE batchno = NEW.batchno;
IF @remainingdays <= 0
THEN SET NEW.status = 'expired';
ELSEIF NEW.qc = 'rejected'
AND NEW.qa != 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QC-rejected';
ELSEIF NEW.qa = 'rejected'
AND NEW.qc != 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QA-rejected';
ELSEIF NEW.qa = 'rejected'
AND NEW.qc = 'rejected'
AND new.status != 'expired'
THEN SET NEW.status = 'QA&QC-rejected';
ELSEIF NEW.status != 'expired'
AND NEW.status NOT LIKE '%rejected'
AND @detailfound = 1
AND @remainingdays <= 0
THEN SET NEW.status = 'empty';
ELSEIF NEW.qc ='quarantine'
AND NEW.status != 'empty'
AND NEW.status != 'expired'
AND @detailfound = 1
AND @available > 0
AND @remainingdays > 0
THEN SET NEW.status = 'quarantine';
ELSEIF NEW.qc = 'approved'
AND NEW.qa = 'approved'
AND NEW.status != 'empty'
AND NEW.status != 'expired'
AND NEW.status NOT LIKE '%rejected'
AND @detailfound = 1
AND @available > 0
AND @remainingdays > 0
THEN SET NEW.status = 'available';
ELSE SET NEW.status = 'unknown';
END IF;
END;
//
delimiter ;
如果没有表格结构或样本数据或wh_profulldetail视图,完全指出这一点非常困难。
答案 1 :(得分:0)
wh_profg与wh_profulldetail之间是否存在一对一的关系?
如果是这样的话,类似于Endre上面的解决方案,但只是进行普通连接而不是针对子查询的连接。
UPDATE {$tprefix}wh_profg a
LEFT OUTER JOIN {$tprefix}wh_profulldetail b
ON a.batchno = b.batchno
SET a.status =
CASE
WHEN b.batchno IS NOT NULL AND b.remainingdays <= 0
THEN 'expired'
WHEN a.QC = 'rejected' and a.QA != 'rejected' and a.status != 'expired'
THEN 'QC-rejected'
WHEN a.QA = 'rejected' and a.QC != 'rejected' and a.status != 'expired'
THEN 'QA-rejected'
WHEN a.QA = 'rejected' and a.QC = 'rejected' and a.status != 'expired'
THEN 'QA&QC-rejected'
WHEN b.batchno IS NOT NULL AND b.available <= 0 and a.status != 'expired' and a.status NOT LIKE '%rejected'
THEN 'empty'
WHEN a.QC ='quarantine' and a.status != 'empty' and a.status != 'expired' and b.batchno IS NOT NULL AND b.available > 0 and b.remainingdays > 0
THEN 'quarantine'
WHEN a.QC ='approved' and a.QA = 'approved' and a.status != 'empty' a.and status != 'expired' a.and status NOT LIKE '%rejected' and b.batchno IS NOT NULL AND available > 0 and remainingdays > 0
THEN 'available'
ELSE 'unknown'
END