2010-09-05 25 views
8

İki veritabanı tablom var: "places" ve "translations". ne zaman sayıSQL: "NOT IN" alt sorgu optimizasyonu veya alternatifleri

SELECT `id`, `name` 
FROM `places` 
WHERE `id` NOT IN (SELECT `place_id` FROM `translations` WHERE `lang` = 'en') 

Bu yerlerin 7 000 kayıtlarla iyi çalıştı, ama çöktü: yerleri isimleri çevirileri henüz belirlenmiş dile çevirileri yok "yerler", kayıtları seçerek yapılır ,

anlıyorum gibi

2006 - MySQL server has gone away

, asıl sorun burada birçok sonuçlarına dönen alt sorgu ise, bu onu nasıl çözebiliriz: çevirilerin 5 000. o zamandan beri, sorgu yaklaşık 10 saniye sürer ve hata verir ulaştı Henüz tercüme edilmeyen tüm yerleri seçmem gerekirse?

Planım B, "çevrilmiş" olarak adlandırılan "yerler" tablosunda yeni bir boole alanı oluşturmak ve dil değiştirdiğimde her seferinde alt sorgunun olmasını engelleyecek şekilde "yanlış" olarak sıfırlamaktır. Ancak, mevcut SQL ifademi değiştirebilir ve ek alan eklemeyi engelleyebilir miyim?

+1

Bir cevap değil, projenizin aşamasında hala mümkün olması halinde daha fazla öneri. "MySQL Server gitti" diye bir şey yokken "MySQL Server gitti" hatalarını yakaladığında, uygulamanızı Postgresql'e taşıdım. – Hao

cevap

13

bariz alternatif:

SELECT 
    `id`, `name` 
FROM 
    `places` 
WHERE 
    NOT EXISTS (
    SELECT 1 FROM `translations` WHERE `id` = `places`.`id` AND `lang` = 'en' 
) 

(translations.id, translations.lang) üzerinde kümelenmiş bileşik endeksi olmamalıdır (kompozit anlamı: Birden fazla alanda üzerinde tek endeks, kümelenmiş araçlar: dizin tablosu nasıl sıralandığını yönetir).

+0

'dan beri geriye hiç bakmadım Teşekkür ederim, tam olarak eksik olduğum şey bu. – krn

+0

@Kernius: Değişikliğin sizin için ne gibi bir farkı karşılaştırdığınızı söyleyebilir misiniz? (endeks önemlidir!) – Tomalak

+1

Bu alanları daha önce dizine ekledim ve hala bu sorunu yaşadım. – krn

0

Bu durumda, en iyi alternatifin 2 ayrı sorgu yapması gerektiğine inanıyorum. Birincinin sonucunu bir değişkende saklamak ve ikincisini kullanmak.