我正在运行一些查询,这些查询将不断变化的数据合并到一个主表中,其中一个查询(下面)似乎运行得非常慢。
设置如下:products
表和products_temp
表具有相同的结构。新数据进入products_temp
表,然后我运行类似于下面的查询,将新数据与主products
表合并。
INSERT INTO products ( name, brand, price, feeds_id, img_url, referral_url, productid, isbn, ean, upc )
SELECT name, brand, price, feeds_id, img_url, referral_url, productid, isbn, ean, upc
FROM products_temp
WHERE feeds_id = 449
AND productid NOT IN (
SELECT productid
FROM products
WHERE feeds_id = 449
)
这两个表都有feeds_id
上的索引,但我觉得这没有任何区别。
例如products
可能包含超过350万行,而products_temp
可能包含50,000以合并products
。
所以我的问题是这需要多长时间?我能以多快的速度制作它?
答案 0 :(得分:0)
是的,这种技术称为Shadow Table trick。
答案 1 :(得分:0)
您可以删除feeds_id
上的索引,并在主表中添加唯一键(feeds_id
,productid
)。因此,您将能够使用INSERT IGNORE
进行合并。请注意索引中字段的顺序 - feeds_id
必须是第一个,因此您可以使用此索引通过feeds_id
执行搜索。
NOT IN
可能导致放缓。根据括号内的内容,查询可能会陷入“准备”状态。
如果您仍然遇到减速,请使用EXPLAIN
或分析功能。
答案 2 :(得分:0)
尝试重构查询并将其设置为LEFT JOIN,检查右侧是否为NULL
INSERT INTO products ( name, brand, price, feeds_id,
img_url, referral_url, productid, isbn, ean, upc )
SELECT A.name, A.brand, A.price,
A.feeds_id, A.img_url, A.referral_url,
A.productid, A.isbn, A.ean, A.upc
FROM
(SELECT * FROM products_temp A WHERE feeds_id = 449) A
LEFT JOIN
(SELECT productid FROM products WHERE feeds_id = 449) B
USING (productid)
WHERE B.productid IS NULL;
还要确保你有这个索引
ALTER TABLE products_temp ADD INDEX feeds_id (feeds_id);
答案 3 :(得分:-1)
你应该大大避免WHERE x不在(选择xxx)。 mysql查询优化器对子查询非常缺陷,例如会忽略索引。