2013-09-06 10 views
18

Bir mysql sorgusuyla garip bir performans sorunu yaşıyorum.mysql: neden sol dizini bir dizin kullanmıyor?

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

Açık bir birleştirmeyi kullanmak istiyorum. Ama sorgu çok daha fazla zaman alır o zaman gerekir.

Birleştirmeyi INNER JOIN olarak değiştirmeyi denedim. Şimdi sorgu gerçekten hızlı, ama sonuç ihtiyacım olan şey değil.

ben açıklamak kullanılan ve şu sonuca vardık:

Ben hem tablolar için ... o zaman bir in ...

type: "ALL" 
possible_keys: NULL 
key: NULL 
key_len: NULL 
ref: NULL 
rows: 90.000/50.000 (the full number of the corresponding table) 

sorgu sonuçlarının AÇIKLAMAK "SOL JOIN" kullanırsanız .

Bir "INNER JOIN" kullanırsanız o zaman AÇIKLAYINIZ verir: Tablo "ürünler" için

:

masa için
Same result as above. 

"pricemaster_products":

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

Her iki tablo var indeksleri ilgili sütunlarda ayarlayın. SOL JOIN’in çok yavaş olması için aklıma gelen tek sebep, endeksi hiç kullanmamaktır. Ama neden olmasın ki?

tablo yapısı aşağıdaki gibidir: için

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'in hangi sürümüne sahipsiniz? –

+0

MySQL sürümü 5.1.70 – Majiy

+1

@juergend: hayır, "bana sol tablodaki tüm verileri ve sağdaki tabloda bulunan verileri verin". tam bir dış birleşim olduğunu düşünüyorsun –

cevap

39

iki İlgili alanlar tam olarak (Latin1 ile KARAKTER SETİ utf8 ve varchar (128) ile varchar (255)) aynı tür yoktu katılmak. Her ikisini de aynı uzunluk ve karakter kümesine ayarlamıştım ve şimdi LEFT JOIN ile yapılan sorgu beklendiği gibi çalışıyor.

+3

Kutsal f *** ing sh * t. Bu şeye tamamen bakıyordum. Teşekkürler. +1 –

+2

Hatalı oluşturulmuş bir tablo (yanlış karakter kümesini kullanarak) sorunları oluştururken benim sorgular biri ile ilgili bir sorun bulmak yardımcı bana çok yardımcı oldu. +1 –

+1

Ben de aynı sorun vardı çok teşekkür ederim ve beni kesinlikle muz kullanıyordu – caro