我用的是SQL Server的bulk insert语句向表里导入大量数据,因为数据要不断累加,所以在表上建立了一个判断插入数据的触发器,如果表中不存在该行的话,执行插入操作,如果表中存在,执行更新操作。
代码:
CREATE TRIGGER [dbo].[inserted_data] on [dbo].[all_card]
instead of insert
AS
BEGIN
IF (NOT EXISTS (SELECT P.card_no
FROM all_card P, inserted I
WHERE P.card_no = I.card_no))
INSERT INTO all_card
SELECT card_no, card_type, unknown, recharge_no, card_state,
past_date, balance, card_deposit, use_balance, recharge_balance
FROM inserted
else
UPDATE all_card
SET card_no = I.card_no,
card_type = I.card_type,
unknown = I.unknown,
recharge_no = I.recharge_no,
card_state = I.card_state,
past_date = I.past_date
balance = I.balance,
card_deposit = I.card_deposit,
use_balance = I.use_balance,
recharge_balance = I.recharge_balance
FROM all_card, inserted I
WHERE all_card.card_no = I.card_no
END
其中,card_no列式主键。我在测试中发现,这个触发器能执行下半段的更新部分,但上半部分的插入数据却始终无法执行,这是为什么呢??
另外,我的bulk insert语句是写在C#里的,代码是:
SqlCommand sqlCmd = new SqlCommand(("bulk insert mysql.dbo.all_card from '") + openFileDialog.FileName + ("'with (batchsize = 1000000, FIELDTERMINATOR = '|', ROWTERMINATOR = '|', CHECK_CONSTRAINTS, FIRE_TRIGGERS)"));
插入的数据量大约是2000万条,感觉插入非常慢,有办法优化吗?
------解决方案--------------------
此触发器有明显的逻辑问题:if exists one then skip others,请使用merge合并。
bulk insert期间,可以改为大容量日志模式,不过速度慢不在insert而在于合并,如果不用update仅是过滤重复会快很多。