MYSQL函数逐渐变慢
我创建了以下函数,通过解析字符串来输入记录:MYSQL函数逐渐变慢,mysql,performance,function,Mysql,Performance,Function,我创建了以下函数,通过解析字符串来输入记录: DROP FUNCTION IF EXISTS RowPerRow ; DELIMITER $$ CREATE FUNCTION RowPerRow() RETURNS VARCHAR(300) BEGIN DECLARE n INT DEFAULT 0 ; DECLARE m INT DEFAULT 0 ; DECLARE i INT DEFAULT 0 ; DECLARE j INT DEFAULT 0 ;
DROP FUNCTION IF EXISTS RowPerRow ;
DELIMITER $$
CREATE FUNCTION RowPerRow()
RETURNS VARCHAR(300)
BEGIN
DECLARE n INT DEFAULT 0 ;
DECLARE m INT DEFAULT 0 ;
DECLARE i INT DEFAULT 0 ;
DECLARE j INT DEFAULT 0 ;
SELECT count(*) FROM Temp0 INTO n ;
WHILE i < n DO
SELECT words INTO m FROM Temp0 LIMIT i, 1 ;
SET j = 1 ;
WHILE j <= m DO
INSERT INTO Temp1 SELECT words,id,api,basin,play,drilltype,tradeflag,score,cnf,fracdate,
fracdateend,state,county,operator,wellname,prodtype,latitude,
longitude,datum,depth,water,nonwater,surfactant,tradename,TRIM(Split_Str(tradename, ',', j)) AS tradename_c,
supplier,purpose,ingredients,cas,additive,fluid
FROM Temp0 LIMIT i,1 ;
SET j = j + 1 ;
END WHILE ;
SET i = i + 1 ;
END WHILE ;
RETURN '' ;
END ;
$$
DROP函数(如果RowPerRow存在);
分隔符$$
创建函数RowPerRow()
返回VARCHAR(300)
开始
声明n INT默认值为0;
声明m INT默认值为0;
声明i INT默认值为0;
声明j INT默认值为0;
从Temp0到n中选择count(*);
而我
从Temp0限制i,1中选择m中的单词;
设置j=1;
虽然j如果问题是“执行相同RBAR(一行接一行)处理但不会逐渐变慢的替代方法的示例是什么”,我可以给出一个这样的示例
如果单词
有一个上限(最大值),那么同样的结果可以在一条语句中实现:
INSERT INTO Temp1
( words, id, api, basin, play, drilltype, tradeflag ,score ,cnf, fracdate, fracdateend, state, county, operator, wellname, prodtype, latitude, longitude, datum, depth, water, nonwater, surfactant, tradename, supplier, purpose, ingredients, cas, additive, fluid
, tradename_c )
SELECT t.words,t.id,t.api,t.basin,t.play,t.drilltype,t.tradeflag,t.score,t.cnf,t.fracdate,t.fracdateend,t.state,t.county,t.operator,t.wellname,t.prodtype,t.latitude,t.longitude,t.datum,t.depth,t.water,t.nonwater,t.surfactant,t.tradename,t.supplier,t.purpose,t.ingredients,t.cas,t.additive,t.fluid
, TRIM(Split_Str(t.tradename, ',', n.i)) AS tradename_c
FROM Temp0 t
JOIN (SELECT 1 AS i UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20) n
ON n.i <= t.words
我们希望随着temp0
中的行数的增加,这个函数会越来越慢。我们还预计可能会得到跳过或重复的结果,尤其是在运行Temp0时有人从Temp0中插入或删除行时。(查询中没有ORDER BY,因此无法保证返回行的顺序。重复运行同一个查询并增加偏移量是返回表中所有行的一种非常低效的方法。处理此RBAR(逐行处理)会很慢。是否有问题?(或者这只是一个状态报告?)同意@spencer7593的评论。请更新问题,说明您的期望,或您对优化的疑问。
DELIMITER $$
CREATE FUNCTION RowPerRow_alt()
RETURNS VARCHAR(300)
BEGIN
-- variables for cursor fetch
-- the datatype of each variable should match the datatype
-- of the expression in SELECT list of the query
DECLARE v_words INT;
DECLARE v_id VARCHAR(100);
DECLARE v_api VARCHAR(100);
DECLARE v_basin VARCHAR(100);
DECLARE v_play VARCHAR(100);
DECLARE v_drilltype VARCHAR(100);
DECLARE v_tradeflag VARCHAR(100);
DECLARE v_score VARCHAR(100);
DECLARE v_cnf VARCHAR(100);
DECLARE v_fracdate VARCHAR(100);
DECLARE v_fracdateend VARCHAR(100);
DECLARE v_state VARCHAR(100);
DECLARE v_county VARCHAR(100);
DECLARE v_operator VARCHAR(100);
DECLARE v_wellname VARCHAR(100);
DECLARE v_prodtype VARCHAR(100);
DECLARE v_latitude VARCHAR(100);
DECLARE v_longitude VARCHAR(100);
DECLARE v_datum VARCHAR(100);
DECLARE v_depth VARCHAR(100);
DECLARE v_water VARCHAR(100);
DECLARE v_nonwater VARCHAR(100);
DECLARE v_surfactant VARCHAR(100);
DECLARE v_tradename VARCHAR(100);
DECLARE v_supplier VARCHAR(100);
DECLARE v_purpose VARCHAR(100);
DECLARE v_ingredients VARCHAR(100);
DECLARE v_cas VARCHAR(100);
DECLARE v_additive VARCHAR(100);
DECLARE v_fluid VARCHAR(100);
DECLARE j INT DEFAULT 0 ;
DECLARE v_tradename_c VARCHAR(100);
DECLARE done TINYINT(1) DEFAULT 0;
-- cursor for Temp0
DECLARE csr CURSOR FOR
SELECT words,id,api,basin,play,drilltype,tradeflag,score,cnf,fracdate,
fracdateend,state,county,operator,wellname,prodtype,latitude,
longitude,datum,depth,water,nonwater,surfactant,tradename,
supplier,purpose,ingredients,cas,additive,fluid
FROM Temp0;
-- setup NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN csr;
rowloop: LOOP
FETCH csr INTO v_words,v_id,v_api,v_basin,v_play,v_drilltype,v_tradeflag,v_score,v_cnf,v_fracdate,v_fracdateend,v_state,v_county,v_operator,v_wellname,v_prodtype,v_latitude,v_longitude,v_datum,v_depth,v_water,v_nonwater,v_surfactant,v_tradename,v_supplier,v_purpose,v_ingredients,v_cas,v_additive,v_fluid;
IF done THEN
LEAVE rowloop;
END IF;
SET j = 1;
WHILE j <= v_words DO
-- split tradename and insert row ti Temp1
SET v_tradename_c = TRIM(Split_Str(v_tradename, ',', j));
INSERT INTO Temp1 ( words, id, api, basin, play, drilltype, tradeflag ,score ,cnf, fracdate, fracdateend, state, county, operator, wellname, prodtype, latitude, longitude, datum, depth, water, nonwater, surfactant, tradename, supplier, purpose, ingredients, cas, additive, fluid,
tradename_c )
VALUES ( v_words,v_id,v_api,v_basin,v_play,v_drilltype,v_tradeflag,v_score,v_cnf,v_fracdate,v_fracdateend,v_state,v_county,v_operator,v_wellname,v_prodtype,v_latitude,v_longitude,v_datum,v_depth,v_water,v_nonwater,v_surfactant,v_tradename,v_supplier,v_purpose,v_ingredients,v_cas,v_additive,v_fluid,
v_tradename_c );
SET j = j + 1 ;
END WHILE;
END LOOP rowloop;
CLOSE csr;
RETURN '' ;
END$$