此過程的要點是刷新並生成每個客戶的ID,以便通過將這些ID添加到某種類型的索引中來加快事物銷售點上的查找過程表名爲PHONENUMS。試圖優化此Interbase過程的運行時間
此過程只是一個數據初始化過程,但目前需要2天才能在此客戶端的數據庫上運行。顯然,這是一個不行,因爲這會讓他們在等待期間停業2天。該函數從PHONENUM_REFRESH_ALL運行,該函數在customers表上運行For循環,然後調用相應處理每條記錄的過程。我粘貼了以下兩個過程。
坦率地說,我嘗試使用Interbase的PLANAnalyzer,試圖縮小是什麼在這個過程中重的部分,但如果我運行通過,如果我正在處理一個單一的記錄,它的真快。我無法找到任何我可以關閉或單獨加入的循環來加速流程,但我們對客戶名稱有類似的流程,它的工作速度非常快,但並排並置並不能給我提供答案。這裏有沒有一些明顯的問題會導致它運行得如此令人難以置信的緩慢?
運行for循環的主程序。
CREATE PROCEDURE PHONENUM_REFRESH_ALL AS
declare variable custid varchar(8);
declare variable KEYWORD varchar(30);
declare variable AREACODE VARCHAR(3);
declare variable PRIMARYTEL VARCHAR(8);
declare variable PRIMARYTELID VARCHAR(8);
declare variable configdefault varchar(8);
begin
/* 2016-03-16 - Creation */
insert into timetracker(time_stamp) values (cast('NOW' as timestamp));
for select custid, areacode, primarytel, PRIMARYTELID
from customers
where (primarytelid || '' is null or primarytelid || '' = '')
and areacode is not null and areacode <> ''
and primarytel is not null and primarytel <> ''
into :custid, :AREACODE, :primarytel,:PRIMARYTELID do
begin
select primarytelid from PHONENUM_REFRESH(:CUSTID,:AREACODE,:PRIMARYTEL,'') into :primarytelid;
update customers set primarytelid = :primarytelid where custid = :custid;
end
insert into timetracker(time_stamp) values (cast('NOW' as timestamp));
END
PHONENUM_REFRESH過程(處理從主過程傳遞的單個記錄)。
CREATE PROCEDURE PHONENUM_REFRESH (
CUSTID VARCHAR(8),
AREACODE VARCHAR(3),
PRIMARYTEL VARCHAR(8),
TRIGG VARCHAR(8)
) RETURNS (
PRIMARYTELID VARCHAR(8)
) AS
DECLARE VARIABLE NEWTELID INTEGER;
DECLARE VARIABLE FOUNDTELID VARCHAR(6);
DECLARE VARIABLE BRANCHID VARCHAR(2);
DECLARE VARIABLE DBTYPE CHAR(2);
DECLARE VARIABLE CNT INTEGER;
DECLARE VARIABLE TELNOTE VARCHAR(40);
DECLARE VARIABLE GENTELIDPREFIX varchar(2);
BEGIN
/* 2013-07-13 V1.0 - Creation. Procedure is binding customer to an existing phonenum (if not bound), creates it if none is matching.
2015-05-04 V1.1 - If matching primarytel is found, update customer's primarytelid
2015-07-22 V1.2 - Not updating CUSTOMERS table if called from trigger (TRIGG = 'trIgg')
2015-08-20 - To add GENTELIDPREFIX for fixing conversion string error with TELID
*/
/* CustId mandatory */
IF ((CUSTID <> '') AND (CUSTID IS NOT NULL)) THEN
BEGIN
IF ((TRIGG = '') OR (TRIGG IS NULL)) THEN
TRIGG = 'SYSDBA';
/* PRIMARYTELID NOT SET, TRY TO GET ONE */
IF ((AREACODE <> '') AND (PRIMARYTEL <> '')) THEN
BEGIN
SELECT MIN(TELID) FROM PHONENUMS WHERE AREACODE=:AREACODE AND PRIMARYTEL=:PRIMARYTEL AND CUSTID=:CUSTID INTO :PRIMARYTELID;
SELECT F_LEFT(config_value,1) FROM branch_config WHERE branchid = '00' and config_name = 'GEN_TELID_PREFIX' into :GENTELIDPREFIX;
/* No PRIMARYTELID found. Go create one with 'PR' */
IF (PRIMARYTELID IS NULL) THEN
PRIMARYTELID = '';
IF (PRIMARYTELID = '') THEN
BEGIN
/* If SF, we force it to use the generators */
SELECT MIN(DBTYPE) FROM DATABASEID INTO :DBTYPE;
IF (DBTYPE = 'SF') THEN
BEGIN
FOUNDTELID='X';
BRANCHID='00';
END
ELSE
BEGIN
SELECT TELID, BRANCHID FROM CTRLFILE WHERE BRANCHID = (SELECT MIN(DBID) FROM DATABASEID) ROWS 1 INTO :FOUNDTELID,:BRANCHID;
END
IF (FOUNDTELID = 'X') THEN
BEGIN
SELECT GEN_ID(GENTELID,1) FROM RDB$DATABASE INTO :NEWTELID;
if ((GENTELIDPREFIX is not null) AND (GENTELIDPREFIX <> '')) then
BEGIN
PRIMARYTELID = GENTELIDPREFIX || CAST(NEWTELID AS VARCHAR(7));
END
ELSE
BEGIN
PRIMARYTELID = BRANCHID || CAST(NEWTELID AS VARCHAR(6));
END
TELNOTE = '';
select count(*) from phonenums where telid = :PRIMARYTELID into :cnt;
IF (CNT = 1) THEN
BEGIN
/* Whaaaaaat? Twilight zone glitch, gotta save the moment! */
TELNOTE = '(Shifted from telid ' || PRIMARYTELID || ')';
SELECT GEN_ID(GENTELID,1) FROM RDB$DATABASE INTO :NEWTELID;
if ((GENTELIDPREFIX is not null) AND (GENTELIDPREFIX <> '')) then
BEGIN
PRIMARYTELID = GENTELIDPREFIX || CAST(NEWTELID AS VARCHAR(7));
END
ELSE
BEGIN
PRIMARYTELID = BRANCHID || CAST(NEWTELID AS VARCHAR(6));
END
END
INSERT INTO PHONENUMS (TELID,PRIMARYTEL,AREACODE,TELTYPE,CUSTID,EDU_,TELNOTE) VALUES(:PRIMARYTELID,:PRIMARYTEL,:AREACODE,'PR',:CUSTID,:TRIGG,:TELNOTE);
END
ELSE
BEGIN
NEWTELID = CAST(FOUNDTELID AS INTEGER) + 1;
if ((GENTELIDPREFIX is not null) AND (GENTELIDPREFIX <> '')) then
BEGIN
PRIMARYTELID = GENTELIDPREFIX || CAST(NEWTELID AS VARCHAR(7));
END
ELSE
BEGIN
PRIMARYTELID = BRANCHID || CAST(NEWTELID AS VARCHAR(6));
END
INSERT INTO PHONENUMS (TELID,PRIMARYTEL,AREACODE,TELTYPE,CUSTID,EDU_) VALUES(:PRIMARYTELID,:PRIMARYTEL,:AREACODE,'PR',:CUSTID,:TRIGG);
UPDATE CTRLFILE SET TELID = :NEWTELID WHERE BRANCHID = :BRANCHID;
END
END
ELSE IF (TRIGG <> 'trIgg') THEN
BEGIN
UPDATE CUSTOMERS SET PRIMARYTELID = :PRIMARYTELID WHERE CUSTID = :CUSTID;
END
END
END
SUSPEND;
END
是的,一些脂肪可以切割,CTRL文件是每個BRANCHID,有50個分支,但是2.5M的客戶,它是多餘的。但是,我將如何一次插入到PHONENUMS中?每個插入都有一個由生成器生成的ID,在插入它們之前,我怎樣才能存儲250萬個ID的ID?那麼id需要創建一個動態插入調用,將所有這些值傳遞給它?我理解你在說什麼,但也許不是我能達到的方式 – Denis