2010-09-05 13 views
8

Tengo dos tablas de base de datos: "lugares" y "traducciones". Las traducciones de los nombres de lugares se realizan mediante la selección de registros de "lugares", que no tienen las traducciones al idioma especificado aún:SQL: optimización de subconsulta "no disponible" o alternativas

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

Esto funcionó bien con 7 000 registros de lugares, pero chocaron cuando el número de traducciones alcanzó el 5 000. Desde entonces, la consulta tarda unos 10 segundos y devuelve el error:

2006 - MySQL server has gone away

Según entiendo, el problema principal aquí es la sub consulta de regresar a muchos resultados, bu cómo podría resolverlo, si necesito seleccionar todos los lugares que aún no están traducidos?

Mi plan B es crear un nuevo campo booleano en la tabla "lugares", llamado "traducido", y restablecerlo a "falso", cada vez que cambio de idioma - eso evitaría tener subconsulta. Sin embargo, ¿tal vez podría simplemente modificar mi declaración de SQL actual y evitar agregar campo adicional?

+1

No es una respuesta, es más una sugerencia si aún es posible en la etapa de su proyecto. Cuando aparecieron los incesantes errores de "El servidor MySQL desapareció", transferí mi aplicación a Postgresql. Nunca miré hacia atrás desde – Hao

Respuesta

13

La alternativa obvia:

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

No debe haber un índice compuesto agrupado sobre (translations.id, translations.lang) (compuesto significa: un único índice en múltiples campos, agrupado medios: el índice gobierna cómo se ordena la tabla).

+0

Gracias, eso es exactamente lo que me estaba perdiendo. – krn

+0

@Kernius: ¿Puedes publicar qué diferencia hace ese cambio para ti en comparación? (¡el índice es importante!) – Tomalak

+1

Había indexado esos campos antes y todavía estaba teniendo ese problema, que simplemente desapareció, cuando cambié a su sugerencia. – krn

0

En este caso, creo que la mejor alternativa es hacer 2 consultas por separado. Almacenando el resultado del primero en una variable y usando el segundo.

Cuestiones relacionadas