2010-07-07 14 views
6

Parece que todas las preguntas sobre este tema son muy específicas, y si bien valoro ejemplos específicos, estoy interesado en los conceptos básicos de la optimización SQL. Me siento muy cómodo trabajando en SQL y tengo experiencia en hardware/software de bajo nivel.Cómo optimizar consultas en una base de datos - Conceptos básicos

Lo que quiero es las herramientas tanto de software tangible, como un método para ver las bases de datos de MySQL que veo regularmente y saber cuál es la diferencia entre las órdenes de declaraciones de unión y de dónde.

Quiero saber por qué un índice ayuda, como, exactamente por qué. Quiero saber específicamente qué sucede de manera diferente, y quiero saber cómo puedo ver lo que está sucediendo. No necesito una herramienta que descomponga cada paso de mi SQL, solo quiero poder examinar y si alguien no puede decirme qué columna indexar, podré sacar una hoja de papel y dentro de un período de tiempo, podrá encontrar las respuestas.

Las bases de datos son complicadas, pero no son TAN complicadas, y debe haber algún material excelente para aprender los conceptos básicos para que sepa cómo encontrar las respuestas a los problemas de optimización que encuentra, incluso si pudiera encontrar el respuesta exacta en un foro.

Por favor, recomiende algunas lecturas que sean concisas, intuitivas y que no tengan miedo de llegar al nivel bajo de tuercas y tornillos. Prefiero los recursos gratuitos en línea, pero si una recomendación de libro demuele la cabeza del clavo que golpea, consideraría aceptarlo.

Respuesta

6

Tiene que hacer una búsqueda de todas las condiciones y para cada unión ... con la condición. Los dos funcionan igual.

Supongamos que escribir

select name 
from customer 
where customerid=37; 

De alguna manera el DBMS tiene que encontrar el registro o registros con idcliente = 37. Si no hay un índice, la única forma de hacerlo es leer cada registro de la tabla que compare el ID de cliente con 37. Incluso cuando encuentra uno, no tiene forma de saber que solo hay uno, por lo que debe seguir buscando otros.

Si crea un índice en customerid, el DBMS tiene formas de buscar el índice muy rápidamente. No es una búsqueda secuencial, sino que, según la base de datos, una búsqueda binaria u otro método eficiente. Exactamente lo que no importa, acepta que es mucho más rápido que secuencial. El índice lo lleva directamente al registro o registros apropiados. Además, si especifica que el índice es "único", la base de datos sabe que solo puede haber uno, por lo que no pierde el tiempo buscando un segundo. (Y el DBMS evitará que la adición de un segundo.)

ahora esto consulta:

select name 
from customer 
where city='Albany' and state='NY'; 

Ahora tenemos dos condiciones. Si tiene un índice en solo uno de esos campos, el DBMS usará ese índice para buscar un subconjunto de los registros, luego los buscará secuencialmente.Por ejemplo, si tiene un índice en estado, el DBMS encontrará rápidamente el primer registro para NY, luego buscará en forma secuencial city = 'Albany', y dejará de buscar cuando llegue al último registro para NY.

Si tiene un índice que incluye ambos campos, es decir "crear índice en el cliente (estado, ciudad)", entonces el DBMS puede acercar de inmediato a los registros correctos.

Si tiene dos índices separados, uno en cada campo, el DBMS tendrá varias reglas que aplica para decidir qué índice usar. Nuevamente, exactamente cómo se hace esto depende del DBMS particular que esté usando, pero básicamente trata de mantener estadísticas sobre el número total de registros, el número de valores diferentes y la distribución de valores. Luego buscará esos registros secuencialmente para aquellos que satisfacen la otra condición. En este caso, el DBMS probablemente observaría que hay muchas más ciudades que estados, por lo que al usar el índice de la ciudad puede acercarse rápidamente a los registros de 'Albany'. Luego los buscará secuencialmente, verificando el estado de cada uno contra 'NY'. Si tiene registros para Albany, California, se omitirán.

Cada unión requiere algún tipo de búsqueda.

Digamos que escribimos

select customer.name 
from transaction 
join customer on transaction.customerid=customer.customerid 
where transaction.transactiondate='2010-07-04' and customer.type='Q'; 

Ahora el DBMS tiene que decidir qué tabla a leer en primer lugar, seleccionar los registros apropiados de allí, y luego encontrar los registros coincidentes en la otra tabla.

Si tiene un índice en transaction.transactiondate y customer.customerid, es probable que el mejor plan sea encontrar todas las transacciones con esta fecha, y luego, para cada una de ellas, encontrar al cliente con la identificación del cliente correspondiente, y luego verificar que el cliente tiene el tipo correcto.

Si no tiene un índice en customer.customerid, entonces el DBMS podría encontrar rápidamente la transacción, pero luego para cada transacción tendría que buscar secuencialmente la tabla del cliente buscando un customerid coincidente. (Esto probablemente sea muy lento.)

Supongamos, en cambio, que los únicos índices que tiene están en transaction.customerid y customer.type. Entonces, el DBMS probablemente usaría un plan completamente diferente. Probablemente escanear la tabla de clientes para todos los clientes con el tipo correcto, luego para cada uno de estos encontrar todas las transacciones para este cliente, y buscarlas secuencialmente para la fecha correcta.

La clave más importante para la optimización es averiguar qué índices realmente ayudarán y crear esos índices. Los índices extra no utilizados son una carga para la base de datos porque requiere mantenimiento para mantenerlos, y si nunca se utilizan, se trata de un esfuerzo desperdiciado.

Puede decir qué índices usará el DBMS para cualquier consulta dada con el comando EXPLAIN. Utilizo esto todo el tiempo para determinar si mis consultas están siendo optimizadas o si debería crear índices adicionales. (Lea la documentación de este comando para obtener una explicación de su resultado).

Advertencia: Recuerde que dije que el DBMS guarda estadísticas sobre el número de registros y el número de valores diferentes, y así sucesivamente en cada tabla. EXPLAIN puede darle un plan completamente diferente hoy de lo que dio ayer si los datos han cambiado. Por ejemplo, si tiene una consulta que une dos tablas y una de ellas es muy pequeña, mientras que la otra es grande, estará sesgada hacia la lectura de la tabla pequeña primero y luego hacia la búsqueda de registros coincidentes en la tabla grande. Agregar registros a una tabla puede cambiar cuál es más grande y, por lo tanto, llevar al DBMS a cambiar su plan. Por lo tanto, debe intentar hacer EXPLICACIONES contra una base de datos con datos realistas. Correr contra una base de datos de prueba con 5 registros en cada tabla es de mucho menos valor que correr contra una base de datos en vivo.

Bueno, hay mucho más que decir, pero no quiero escribir un libro aquí.

+0

Wow, mucha información, gracias, he aprendido un par de cosas al leer esto que puedo usar de inmediato – walnutmon

7

Digamos que estás buscando a un amigo en otra ciudad. Una forma sería ir de puerta en puerta y preguntar si esta es la casa que está buscando. Otra forma es mirar el mapa.

El índice es el mapa a una tabla. Puede decirle al motor de DB exactamente dónde está lo que estás buscando. Por lo tanto, indexa cada columna que cree que tendrá que buscar y omite las columnas de las que solo está leyendo datos y nunca las busca.

Buena lectura técnica about indices y about ORDER BY optimization. Y si quiere ver qué está sucediendo exactamente, quiere la declaración EXPLAIN.

+1

Además, merece la pena observar el registro lento de mysql. http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html – Pete

+0

Me interesa particularmente cómo los índices afectarán las uniones, uso mucho las uniones y realmente no entiendo cómo trabajan en un nivel bajo Por ejemplo, ¿importa si tiene dos columnas indexadas que pueden ser muy grandes uniéndose entre sí? ¿Cómo se asigna y atraviesa el espacio para las uniones? ¿Qué pasa si ambos están indexados? ¿Qué sucede si ninguno de ellos está indexado? – walnutmon

+0

Básicamente, todo el capítulo 7.2 del manual de MySQL es interesante. Si una columna no está indexada, se necesitan como máximo n comparaciones para encontrar algo. Si es así, necesita como mucho log (n) comparaciones. La longitud del dato es definitivamente un factor, pero el índice es más importante. Sin embargo, creo que casi nunca me uno a campos no enteros. Mi política es que, si tiene una posibilidad no trivial de repetirse, debería tener una tabla y una clave principal. Y preguntas "¿y si?" Como la suya se responden mejor construyendo el modelo y ejecutando 'EXPLAIN' en las consultas de muestra. – Amadan

2

No pienses en optimizar las bases de datos. Piensa en optimizar las consultas.

Generalmente, optimiza un caso a expensas de otros. Sólo tienes que decidir qué casos que le interesa.

1

"Me interesa sobre todo en cómo afectarán los índices se une a"

A modo de ejemplo, voy a tomar el caso de la combinación de igualdad (seleccionar de una , B DÓNDE Ax = Por).

Si no hay ningún índice (lo cual es posible en teoría, pero no en SQL), básicamente la única forma de calcular la unión es tomar toda la tabla A y dividirla en x, tomar la totalidad table y y participen sobre y, luego haga coincidir las particiones, y finalmente, para cada par de particiones coincidentes, calcule las filas de resultados. Eso es costoso (o incluso totalmente imposible debido a las restricciones de memoria) para todas las tablas excepto para las más pequeñas.

La misma historia si existen índices en A y/o B, pero ninguno de ellos tiene x resp. y como su primer atributo.

Si existe un índice en x, pero no en y (o por el contrario), se abre otra posibilidad: escanee la tabla B, busque cada valor de fila y, busque ese valor en el índice y busque el A correspondiente filas para calcular la unión.Tenga en cuenta que esto aún no le hará ganar mucho si no se aplican otras restricciones adicionales (AND z = ...) - excepto en el caso en que haya pocas coincidencias entre los valores xey.

Si existen índices ordenados (no se ordenan los índices basados ​​en hash) tanto en x como en y, se abre una tercera posibilidad: hacer un escaneo correspondiente en los índices (los índices mismos probablemente sean más pequeños que las tablas ellos mismos, por lo que escanear el índice en sí tomará un tiempo más corto), y para los valores x/y coincidentes, calcule la combinación de las filas correspondientes.

Esa es la línea de base. Las variaciones surgen para las uniones en x> y etc.

1

No conozco las herramientas MySql, pero en MS SqlServer tienes una herramienta que muestra todas las operaciones que una consulta tomaría y cuánto del tiempo de procesamiento de la totalidad la consulta tomaría.

El uso de esta herramienta me ayudó a entender cómo el optimizador de consultas optimiza las consultas mucho más de lo que creo que cualquier libro podría ayudar porque lo que el optimizador hace a menudo no es fácil de entender. Al ajustar la consulta y posiblemente la base de datos subyacente, pude ver cómo cada cambio afectó el plan de consulta. Hay ciertos puntos clave en la escritura de consultas, pero a mí me parece que ya tiene una idea de aquellos para optimizar en su caso, es mucho más acerca de esto que cualquier regla general. Después de algunos años de desarrollo de BD, eché un vistazo a algunos libros específicamente destinados a la optimización de la base de datos en SQL Server y encontré muy poca información útil.

Google rápido se le ocurrió esto: http://www.mysql.com/products/enterprise/query.html que suena como una herramienta similar.

Esto fue por supuesto en un nivel de consulta, las optimizaciones de nivel de base de datos son una herradura de pescado diferente, pero aquí están viendo parámetros como la base de datos en los discos duros, etc. Al menos en SqlServer puede seleccione dividir las tablas en diferentes discos duros e incluso discos, y esto puede tener un gran efecto porque las unidades y los cabezales de las unidades pueden funcionar en paralelo. Otra es cómo puede crear sus consultas para que la base de datos pueda ejecutarlas en varios subprocesos y procesadores en paralelo, pero ambos problemas dependen nuevamente del motor de la base de datos e incluso de la versión que esté utilizando.

Cuestiones relacionadas