2011-12-21 12 views
6

Evitar el uso de IN (...) al seleccionar en campos indexados, matará el rendimiento de la consulta SELECT.¿Por qué usar IN (...) al seleccionar en campos indexados, matará el rendimiento de la consulta SELECT?

Me encontraron esta aquí: https://wikis.oracle.com/pages/viewpage.action?pageId=27263381

Puede explicarlo? ¿Por qué eso matará el rendimiento? ¿Y qué debería usar en lugar de IN? "O" declaración tal vez?

+0

@BillKarwin paging ... – ajreal

+0

+1 para el enlace =) – newtover

Respuesta

-1

Creo que IN se trata de la misma manera que un grupo de quirófanos, por lo que el uso de R no ayudará.

Una alternativa es crear una tabla temporal para contener los valores de su cláusula IN y luego unir con esa tabla temporal en su SELECCIÓN.

Por ejemplo:

CREATE TEMPORARY TABLE temp_table (v VARCHAR) 

INSERT INTO temp_table VALUES ('foo') 
INSERT INTO temp_table VALUES ('bar') 

SELECT * FROM temp_table tmp, orig_table orig 
WHERE temp_table.v = orig.value 

DROP TEMPORARY TABLE temp_table 
2

Debido a que MySQL no puede optimizarlo.

Aquí se muestra un ejemplo: (. Lástima por enlace externo no muestra correctamente aquí)

explain select * from keywordmaster where id in (1, 567899); 

plan

aquí otra pregunta:

explain 
    select * from table where id = 1 
    union 
    select * from keywordmaster where id = 567899 

plan

Como puede ver en la segunda consulta obtenemos ref como const y type es const en lugar de rango. MySQL no puede optimizar escaneos de rango.

+0

sin embargo, la segunda consulta parece tomar más tiempo, al menos, en mis conjuntos de datos. – newtover

+0

@newtover esto se aplica solo 'al seleccionar en campos indexados' –

+1

También miré en http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716, y dice: "La salida de EXPLAIN puede a veces hace que sea difícil saber si MySQL realmente está buscando un rango de valores, o una lista de valores ... No solo estamos siendo selectivos: estos dos tipos de acceso de índice funcionan de manera diferente. La condición de rango hace que MySQL ignore cualquier columna adicional en el índice, pero la condición de igualdad múltiple no tiene esa limitación ". – newtover

3

A decir verdad, esa afirmación contradice muchos consejos que he leído en libros y artículos sobre MySQL.

Aquí se muestra un ejemplo: http://www.mysqlperformanceblog.com/2010/01/09/getting-around-optimizer-limitations-with-an-in-list/

Por otra parte, expr IN(value, ...) sí tiene mejoras adicionales para hacer frente a las listas de valores grandes, ya que se supone que debe ser utilizado como una alternativa útil a ciertos range consultas:

Si todos los valores son constantes, se evalúan según el tipo de expr y se ordenan. La búsqueda del artículo se realiza mediante una búsqueda binaria. Esto significa que IN es muy rápido si la lista de valores de IN consta de constantes.

El uso excesivo de INs puede dar lugar a consultas lentas. Algunos casos se indican en the article.

0

Prior to MySQL 5.0 Parece que mySQL solo usaría un índice único para una tabla. Por lo tanto, si tuviera un SELECT * FROM tbl WHERE (a = 6 OR b = 33), podría elegir utilizar el índice a o el índice b, pero no ambos. Tenga en cuenta que dice campos, plural. Sospecho que los consejos provienen de ese momento y el resultado fue la unión de los resultados de OR, así:

SELECT * FROM tbl WHERE (a = 6) 
UNION 
SELECT * FROM tbl WHERE (b = 33) 
Cuestiones relacionadas