【发布时间】:2013-09-10 16:48:13
【问题描述】:
我遇到了一个奇怪的 mysql 查询性能问题。
SELECT
`pricemaster_products`.*,
`products`.*
FROM `pricemaster_products`
LEFT JOIN `products`
ON `pricemaster_products`.`ean` = `products`.`products_ean`
我明确地想使用左连接。但是查询花费的时间比它应该的要长。
我尝试将联接更改为 INNER JOIN。现在查询确实很快,但是结果不是我需要的。
我用explain,得出以下结论:
如果我使用“LEFT JOIN”,那么查询的解释会导致...
type: "ALL"
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 90.000 / 50.000 (the full number of the corresponding table)
...对于两个表。
如果我使用“INNER JOIN”,则 EXPLAIN 给出:
对于表“产品”:
Same result as above.
对于表“pricemaster_products”:
type: "ref"
possible_keys: "ean"
key: ean
key_len: 767
ref: func
rows: 1
extra: using where
两个表都在相关列上设置了索引。我能想到的 LEFT JOIN 这么慢的唯一可能原因是根本不使用索引。但为什么不呢?
表结构如下:
CREATE TABLE IF NOT EXISTS `pricemaster_products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`provider` varchar(255) CHARACTER SET utf8 NOT NULL,
`ean` varchar(255) CHARACTER SET utf8 NOT NULL,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`gnp` double DEFAULT NULL,
`vat` int(11) DEFAULT NULL,
`cheapest_price_with_shipping` double DEFAULT NULL,
`last_cheapest_price_update` int(11) DEFAULT NULL,
`active` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `ean` (`ean`),
KEY `title` (`title`),
KEY `gnp` (`gnp`),
KEY `vat` (`vat`),
KEY `provider` (`provider`),
KEY `cheapest_price_with_shipping` (`cheapest_price_with_shipping`),
KEY `last_cheapest_price_update` (`last_cheapest_price_update`),
KEY `active` (`active`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=58436 ;
CREATE TABLE IF NOT EXISTS `products` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`products_ean` varchar(128) DEFAULT NULL,
`products_status` tinyint(1) NOT NULL DEFAULT '1',
[a lot more of fields with no connection to the query in question]
PRIMARY KEY (`products_id`),
KEY `products_status` (`products_status`),
KEY `products_ean` (`products_ean`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=105518 ;
【问题讨论】:
-
你有哪个版本的 MySQL?
-
MySQL 版本为 5.1.70
-
@juergend:不,它是“给我左表中的所有数据以及右表中可用的所有数据”。你正在考虑一个完整的外部连接
-
您在这里处理多少条记录?内连接总是比左连接快,尤其是在处理大量记录时。
-
好吧,
ean是一个表是varchar(255)和CHARACTER SET utf8,另一个是varchar(128)和latin1。这可能是相关的。
标签: mysql join left-join inner-join