有没有办法在MySql中使用.Net / Connector批量存储过程调用来提高性能?
这是场景......我正在使用一个存储过程接受一些参数作为输入。此过程基本上检查是否应更新现有记录或插入新记录(我没有使用INSERT INTO .. ON DUPLICATE KEY UPDATE因为检查涉及日期范围,所以我无法真正制作主键标准)。
我想多次调用这个程序(假设批量为1000左右)。我当然可以使用一个MySqlConnection和一个MySqlCommand实例,并不断更改参数值,并调用.ExecuteNonQuery()。
我想知道是否有更好的方法来批量调用这些电话?
想到的唯一想法是手动构造一个字符串,如'call sp_myprocedure(@parama_1,@ paramb_1);调用sp_myprocedure(@parama_2,@ paramb2); ...',然后创建所有适当的参数。我不相信这会比多次调用.ExecuteNonQuery()更好。
有什么建议吗?谢谢!
编辑:更多信息
我实际上是在定期尝试存储来自外部数据源的数据。基本上我正在使用域名拍卖的rss源(来自各种来源,如godaddy,pool等),并使用此存储过程更新带有拍卖信息的表(让我们称之为sp_storeSale)。现在,在此表中存储了销售信息,我想保留给定域的销售历史记录,因此我有一个域表和一个 sale 表。 sale 表与域表具有多对一关系。
这是存储过程:
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE PROCEDURE `DomainFace`.`sp_storeSale`
(
middle VARCHAR(63),
extension VARCHAR(10),
brokerId INT,
endDate DATETIME,
url VARCHAR(500),
category INT,
saleType INT,
priceOrBid DECIMAL(10, 2),
currency VARCHAR(3)
)
BEGIN
DECLARE existingId BIGINT DEFAULT NULL;
DECLARE domainId BIGINT DEFAULT 0;
SET @domainId = fn_getDomainId(@middle, @extensions);
SET @existingId = (
SELECT id FROM sale
WHERE
domainId = @domainId
AND brokerId = @brokerId
AND UTC_TIMESTAMP() BETWEEN startDate AND endDate
);
IF @existingId IS NOT NULL THEN
UPDATE sale SET
endDate = @endDate,
url = @url,
category = @category,
saleType = @saleType,
priceOrBid = @priceOrBid,
currency = @currency
WHERE
id = @existingId;
ELSE
INSERT INTO sale (domainId, brokerId, startDate, endDate, url,
category, saleType, priceOrBid, currency)
VALUES (@domainId, @brokerId, UTC_TIMESTAMP(), @endDate, @url,
@category, @saleType, @priceOrBid, @currency);
END IF;
END
正如您所看到的,我基本上是在寻找一个不是“已过期”的现有记录,但拥有相同的域名和经纪人,在这种情况下我认为拍卖还没有结束,而且数据是更新现有拍卖。否则,我认为拍卖已经结束,这是一个历史记录,我得到的数据是新的拍卖,所以我创建了一个新的记录。
希望清除我想要实现的目标:)
答案 0 :(得分:0)
我不完全确定你要做什么,但听起来有点像家务或维护,所以我不会因为发布以下建议而感到羞耻。
为什么不将所有逻辑移入数据库并在服务器端处理它? 以下示例使用游标(shock / horror),但在这种情况下使用它们是完全可以接受的。
如果你可以完全避免使用游标 - 那很好,但我的建议主要是将逻辑从应用程序层移回数据层以节省往返次数。您将调用以下sproc一次,它将在单个调用中处理整个数据范围。
call house_keeping(curdate() - interval 1 month, curdate());
此外,如果您可以提供有关您尝试做的更多信息,我们可能会建议其他方法。
示例存储过程
drop procedure if exists house_keeping;
delimiter #
create procedure house_keeping
(
in p_start_date date,
in p_end_date date
)
begin
declare v_done tinyint default 0;
declare v_id int unsigned;
declare v_expired_date date;
declare v_cur cursor for
select id, expired_date from foo where
expired_date between p_start_date and p_end_date;
declare continue handler for not found set v_done = 1;
open v_cur;
repeat
fetch v_cur into v_id, v_expired_date;
/*
if <some condition> then
insert ...
else
update ...
end if;
*/
until v_done end repeat;
close v_cur;
end #
delimiter ;
只是因为你觉得我在建议你可能想要阅读的游标时已经完全疯了 Optimal MySQL settings for queries that deliver large amounts of data?
希望这会有所帮助:)