La optimización del rendimiento de SQL es un gran desafío para los programadores, porque a menudo nos encontramos con este problema: cuando desarrollamos un proyecto, sentimos que la experiencia funcional de probarlo nosotros mismos es realmente buena, pero después de que se lanza el proyecto real, Con el aumento masivo En datos, la experiencia del cliente con el sistema es cada vez peor. Por supuesto, además del marco y el código irrazonable, la razón principal es que SQL no se ha optimizado, lo que ha provocado que el sistema se vuelva cada vez más lento.
Como trabajo en una pequeña empresa, hago de todo. ¡Creo que a veces es mejor tratar los síntomas que tratar la causa raíz! Hay varias cuestiones a las que prestar atención:
1. El diseño de la tabla de la base de datos debe ser razonable, especialmente el diseño de la clave principal. Si la cantidad de datos en la tabla es muy grande, el diseño de la clave principal no debe ser significativo, al igual que ROWID, como el ROWID. GUID de SQL Server, UUID de Hibernate, etc. Por supuesto, algunas tablas del diccionario de datos se pueden procesar de manera flexible y no es necesario considerar que deben ser claves primarias físicas. En el diseño de claves primarias, generalmente no se utilizan claves primarias compuestas.
2. Indexación razonable. Index es una herramienta poderosa y un buen medio para acelerar nuestra consulta de datos. Pero no agregue todos los campos. El principio de indexación es como el índice de un libro. Si el índice de su libro tiene casi el mismo nombre, puede imaginar lo siguiente: ¿qué tan rápido puede encontrar el contenido específico según el índice? ? El índice no tiene por qué ser necesariamente único, pero tampoco debe tener demasiados registros idénticos. Además, si se agregan más índices, el espacio de tabla TEMP aumentará. Al exportar la tabla e importarla a otra base de datos, los índices también reducirán la eficiencia de la importación. En este momento, también encontrará que el espacio de tabla UNDOTBS01. es anormalmente grande. Por tanto, el índice es un arma de doble filo y debe aplicarse de forma razonable.
3. He visto algunos artículos muy profesionales sobre optimización de SQL en Internet, pero siento que no he podido utilizarlos en mi proyecto. En cambio, continué experimentando y descubriendo algunos principios básicos durante el proyecto. Personalmente, creo que solo hay un principio de optimización de SQL, que es reducir el alcance de la consulta tanto como sea posible. Esto definitivamente mejorará la eficiencia, y el propio Oracle puede optimizar el SQL que escribimos, así que lo que tenemos que hacer es. Reduzca el alcance de la consulta tanto como sea posible. Hablando de esto, creo que todos definitivamente pensarán que la indexación es una herramienta poderosa para mejorar la velocidad de la consulta. De hecho, es solo un medio y también surge del principio de reducir el alcance de la consulta. .
La mayoría de los SQL que deben optimizarse son consultas de unión de varias tablas, y las uniones de varias tablas también incluyen uniones horizontales y uniones verticales. La que más utilizamos son las uniones verticales. La conexión horizontal generalmente significa que las estructuras de campos de dos tablas son básicamente las mismas, y algunos registros de datos de una tabla deben cambiarse a algunos registros de otra tabla, es decir, Filas + Filas. Conexión vertical significa que tomamos algunos campos para consultar de la tabla A y algunos campos para consultar de la tabla B, y luego conectamos las tablas extraídas de las tablas A y B verticalmente usando la parte común, es decir, Columnas + Columnas.
Declaración de unión horizontal: seleccione a.column1,a.column2 de la tablaA una unión, todos seleccione b.column1,b.column2 de la tablaB b
Tenga en cuenta que cuando se conecta horizontalmente, el número de columnas debe ser el mismo y los tipos de datos de las columnas del campo correspondiente deben ser los mismos. De hecho, puedes pensar en las tablas que se van a unir como una copia de la otra, exactamente iguales. Alguien puede preguntar, si las columnas que quiero fusionar tienen columnas diferentes, o no hay ninguna columna, entonces puede usar el siguiente método
seleccione d.dname,d.loc de dept1 d union all seleccione '' dname, e.loc de dept e, mire "'' dname", podemos encontrar fácilmente que puede encontrar un sustituto, use una cadena vacía en su lugar. No hay campos, por lo que se pueden fusionar.
Declaración de unión vertical: seleccione a.column1,a.column2 de la tablaA una unión externa completa seleccione b.column3,b.column4 de la tablaB b en a.aid=b.bid donde..., este es un formato de unión externa completa. Esta velocidad es realmente muy rápida, pero es posible que no le guste la consulta porque hay algunas filas de resultados que quizás no desee ver en absoluto. En circunstancias normales, utilizamos más la unión exterior izquierda y la unión exterior derecha. La diferencia entre las dos es que la unión exterior izquierda se basa principalmente en la tabla correspondiente al campo de unión a la izquierda después de, y la unión exterior derecha está justo enfrente. Por supuesto, también puedes utilizar la unión izquierda y la unión derecha. Durante el uso, todavía descubrí que las conexiones externas son relativamente más rápidas.
Para acelerar la eficiencia de las consultas de conexión vertical, la forma es anidar consultas. El siguiente es un ejemplo real del proyecto:
seleccione c.id de cliente,c.dinero recibido,c.collector de peaje,c.fecha de recepción,c.añomes,c.cargo por retraso recibido,
c.tarifa recibida,c.recibidoappend,c.jmman,c.jmmmoney,c.nombre,d.chargeint de
(seleccione un ID de cliente, un dinero recibido, un cobrador de peaje, una fecha de recepción, un año y mes, un cargo por retraso en la recepción,
una tarifa recibida, un anexo recibido, un jmman, un jmmoney, b.nombre de
(seleccione rf.id.cliente,rf.dinerorecibido,rf.collector de peaje,rf.fecha de recepción,rf.añomes,rf.cargo por retraso recibido,
rf.receivedfee,rf.receivedappend,rf.jmman,rf.jmmmoney de sf_receivedfee rf donde
rf.electriccompanyid='1000000001' y rf.dealsign=0 y rf.yearmonth in(200811,200901,200903,200804,200805,200806,200807)
y rf.customerid=1000052545) una unión externa izquierda (seleccione xe.employeeid,xe.name de xt_employee xe) b en a.tollcollector=b.employeeid)
c unión externa izquierda (seleccione cp.chargeint,cp.customerid de sf_chargeprotocol cp donde cp.customerid=1000052545) d
en c.customerid=d.customerid
Puede ver que en este ejemplo, primero filtramos los registros que necesitamos de cada tabla usando casi las mismas condiciones y luego fusionamos los registros. En el uso real, descubrí que esto es casi 60 veces más rápido que la consulta de enlace directo. Aunque es feo y difícil de leer, resuelve el problema de rendimiento de SQL. El principio que utiliza sigue siendo limitar el alcance primero y luego realizar una consulta de conexión. Si nos conectamos y luego filtramos, es equivalente a fusionar dos tablas y luego recuperar datos según las condiciones.