2013-09-06 25 views
18

私はmysqlクエリで奇妙なパフォーマンスの問題に直面しています。mysql:なぜ左結合はインデックスを使用しないのですか?

SELECT 
`pricemaster_products`.*, 
`products`.* 
FROM `pricemaster_products` 
LEFT JOIN `products` 
ON `pricemaster_products`.`ean` = `products`.`products_ean` 

私は明示的に左結合を使用します。しかし、クエリーにはもっと時間がかかります。

私は結合をINNER 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) 

クエリ結果のEXPLAIN「LEFT JOINを」使用している場合。

私は "INNER JOINを" を使用する場合は、与えEXPLAIN:両方のテーブルにインデックスを持っている

type: "ref" 
possible_keys: "ean" 
key: ean 
key_len: 767 
ref: func 
rows: 1 
extra: using where 

テーブル "製品" の場合:

Same result as above. 

テーブルについて "pricemaster_productsを"関連する列に設定します。 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 ; 
+0

ご使用のMySQLのバージョンは? –

+0

MySQLのバージョンは5.1.70 – Majiy

+1

です@juergend:いいえ、それは "私にすべてのデータを左側のテーブルに与え、すべてのデータを右側のテーブルで利用できます"です。あなたは完全な外部参加を考えています –

答えて

39

参加するための2つの関連するフィールドがまったく同じタイプ(LATIN1を持つキャラクタ・セットUTF8とvarcharデータ型はvarchar(255)(128))を持っていませんでした。同じ長さと文字セットの両方を設定しましたが、LEFT JOINのクエリは期待通りに機能します。

+3

Holy f *** ing sh * t。私はこのことを完全に見落としていました。ありがとう。 +1 –

+2

ありがとうございました。これは、間違って(誤った文字セットを使用して)作成されたテーブルが問題を作成していたクエリに問題があるのを助けてくれてありがとうございます。 +1 –

+1

私はこの同じ問題を抱えてくれてありがとう、それは私に絶対的にバナナを運転していた – caro

関連する問題