这是我在MySQL中尝试做的最佳查询吗?

时间:2010-07-21 21:35:14

标签: sql mysql query-optimization

我正在运行一些查询,这些查询将不断变化的数据合并到一个主表中,其中一个查询(下面)似乎运行得非常慢。

设置如下: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

所以我的问题是这需要多长时间?我能以多快的速度制作它?

4 个答案:

答案 0 :(得分:0)

是的,这种技术称为Shadow Table trick

答案 1 :(得分:0)

您可以删除feeds_id上的索引,并在主表中添加唯一键(feeds_idproductid)。因此,您将能够使用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查询优化器对子查询非常缺陷,例如会忽略索引。