2011-03-05 6 views
5

Soy el webmaster de una de las principales universidades de EE. UU. Tenemos una gran cantidad de solicitudes en nuestro sitio web, que he creado y he estado a cargo durante los últimos 7 años más o menos. He estado creando funciones cada vez más complejas en nuestro sitio web y siempre he tenido la costumbre de cargar la mayor parte de la carga de programación en nuestro servidor Microsoft SQL multiprocesador, utilizando procedimientos almacenados, vistas, etc. en lo que no se puede hacer con PHP, ASP o Perl desde el servidor web de IIS. Ambos servidores son máquinas muy potentes y capaces. Dado que he estado haciendo esto solo durante tanto tiempo sin nadie más para intercambiar ideas, tengo curiosidad de saber si mi enfoque es ideal para situaciones de mayor carga que tendremos en el futuro.Mejor práctica: colocar la carga en SQL o servidor web?

Mi pregunta es: ¿es una mejor práctica cargar más carga en el servidor SQL utilizando sentencias SELECT anidadas, vistas, procedimientos almacenados y funciones agregadas, o debería estar procesando múltiples consultas más simples y procesándolos a través del servidor? secuencias de comandos en tiempo de compilación como PHP? ¿Sigues o sigues mejorando?

Recientemente me interesé más en el rendimiento después de hacer algunas huellas de carga y aprendí cuánto he estado poniendo sobre los hombros del servidor SQL. Tanto el servidor web como los servidores SQL son rápidos y receptivos a lo largo del día, y casi sin importar cuánto los puse, pero me gustaría estar preparado, capacitarme y actualizar mis mejores prácticas de código optimizadas en mente. el momento en que se vuelve importante.

Gracias por su asesoramiento y aportes.

Respuesta

9

Usted pone cada capa en su pila al uso en el dominio que se ajusta mejor.

No tiene sentido que su servidor de base de datos envíe 1000 filas y use PHP para filtrarlas si una cláusula WHERE o cláusula GROUP fuera suficiente. No es óptimo llamar a la base de datos para agregar dos enteros (SELECT 5+9 funciona bien, pero php puede hacerlo por sí mismo, y se guarda la ida y vuelta).

Es probable que desee examinar escalabilidad: ¿qué partes de su aplicación se pueden dividir en múltiples procesos? Si todavía está utilizando solo 2 capas (script & db), hay mucho espacio para escalar allí. Pero siempre comienza con el cuello de botella primero.

Algunos ejemplos: albergar contenidos estáticos en CDN, usar el almacenamiento en caché para sus páginas, leer sobre nginx y memcached, usar nosql (mongoDB), considerar la fragmentación, considerar la replicación.

+0

Gracias Konerak. Teniendo en cuenta que ni siquiera sé cuáles son muchas de esas cosas, tengo un verdadero trabajo de investigación por delante. Hasta ahora, realmente no he tenido que preocuparme por la carga, todo funciona sin problemas, debido a la importancia que le doy a la eficiencia en mi código, pero ahora adquirir el hábito y aprender lo que debería hacer de ahora en adelante es un lujo agradable que puedo permitir ahora mismo. Gracias por los consejos. Los usaré bien. – Brak

4

Mi opinión es que generalmente (la mayoría) lo mejor es permitir que los servidores web procesen. Dos puntos:

Lo primero es la escalabilidad. Una vez que su aplicación tenga suficiente uso, deberá comenzar a preocuparse por el equilibrio de carga. Y es mucho más fácil incluir un par de servidores web adicionales apuntando a una base de datos común que configurar un clúster de base de datos distribuida. Por lo tanto, es mejor que se quite la mayor cantidad posible de datos de la base de datos y que permanezca en una sola máquina el mayor tiempo posible.

El segundo punto que me gustaría hacer es sobre la optimización de las consultas. Esto dependerá mucho de las consultas que esté utilizando y del back-end de la base de datos. Cuando comencé a trabajar con bases de datos, caí en la trampa de realizar complejas consultas SQL con múltiples JOINs que obtenían exactamente los datos que quería, incluso si se trataba de cuatro o cinco tablas diferentes.Pensé que "para eso está la base de datos, hagamos que haga el trabajo duro"

Descubrí rápidamente que estas consultas llevaban demasiado tiempo para ejecutarse y, a menudo, bloqueaban la base de datos de otras solicitudes. Si bien puede ser ineficiente dividir su consulta en varias solicitudes (por ejemplo, en un bucle for), a menudo encontrará que ejecutar múltiples pequeñas consultas con índices rápidos hará que su aplicación se ejecute mucho mejor que tratar de pasar todo el trabajo duro. a la base de datos

+0

Puntos bien tomados. Eso tiene mucho sentido. Tu antigua forma de pensar es casi exactamente lo que estaba haciendo, y pinta una buena imagen de en qué dirección debería ir. Gracias por su aporte. – Brak

+0

¿De verdad? Las consultas pequeñas y simples, incluso en un ciclo de tamaño algo pequeño, pueden ser más rápidas que una combinación grande para obtener la misma información. Hombre, he estado saltando a través de aros para crear uniones por miedo a que las consultas en un bucle sean A Bad Thing (TM). Por supuesto, podría (¡debería!) Probarlo yo mismo con un benchmarking decente, pero nunca llevé a cabo la comparación sobre la base de que una consulta de unión única es "evidentemente" más rápida que la alternativa. Pero supongo que no, ¿eh? No quiero secuestrar el hilo/respuesta, pero serían bienvenidos otros comentarios sobre este punto. –

+0

@David Weinraub: No es realmente para combinaciones individuales (a menos que haya algo REALMENTE incorrecto en el diseño de su base de datos). Quise decir que cuando estás recogiendo datos de todas partes, resiste el impulso de escribir una declaración monolítica para captar todo de una vez. Para ver un ejemplo de las mejores prácticas, revise los diversos marcos de desarrollo, por ejemplo, CakePHP, Ruby on Rails, etc., y vea cómo se encargan de obtener datos relacionados lejanamente. –

0

En primer lugar, es posible que desee comprobar si hay alguna carga que se puede eliminar por caché del cliente (.js, .css, HTML estático e imágenes) y el uso de tecnologías como AJAX para hacer actualizaciones parciales de pantallas: esto eliminará la carga en los servidores web y sql.

En segundo lugar, vea si hay carga de sql que se puede reducir con el almacenamiento en caché del servidor web, p. datos estáticos o de baja actualización: si tiene muchas páginas de "contenido" en sus sistemas, eche un vistazo a las técnicas comunes de caché de CMS que se escalarán para permitir que muchos usuarios vean los mismos datos sin tener que reconstruir la página o acceder a la base de datos.

+0

Gracias nonnb. De hecho, comencé a hacer más llamadas a la base de datos AJAX y JSON durante el último año, lo que mejoró la velocidad y redujo la carga en ambos servidores, por lo que es un buen consejo. El procesamiento del lado del cliente es mucho menos costoso que el procesamiento del lado del servidor. He estado reescribiendo una gran cantidad de mi antiguo código de Perl de página completa en JavaScript, AJAX/JSON y comandos PHP que realmente me parecen ágiles.Aún así, algunas de mis llamadas de bases de datos de PHP están solicitando consultas SQL complejas, EXEC que ejecutan consultas anidadas, etc. He estado interesado en el almacenamiento en caché, así que ciertamente tendré que buscar más en él. – Brak

0

Tiendo a hacer tanto como sea posible fuera de la base de datos, viendo las llamadas a bases de datos como costosas/intensivas en tiempo.

Por ejemplo, al realizar una selección en una tabla de usuario con los campos name_given y name_family, podría engordar la consulta para devolver una columna llamada full_name construida por concatenación. Pero ese tipo de cosas se puede hacer fácilmente en un modelo en su lenguaje de scripting del lado del servidor (PHP, Ruby, etc.).

Por supuesto, hay casos en que el db es el lugar más "natural" para realizar una operación. Pero, en general, me inclino más a poner la carga en el servidor web y optimizar allí con muchas de las técnicas observadas en otras respuestas.

+0

Heh, he hecho exactamente eso en muchos casos en mi servidor, pero solo si hay una razón SQL para hacerlo, como si tuviera que ordenar o agrupar por algo concatenado. Una de las cosas así que hago es obtener 'user_name_first, user_name_last, user_alias, COALESCE (user_alias, user_name_first) AS userNameFirst'. De esa manera obtengo un registro que ya tiene el nombre preferido del usuario. – Brak

+0

Si está ordenando o filtrando por un campo concatenado, podría ser mejor agregar un campo adicional y hacer la concatenación cuando inserta la fila. De esta forma, puede indexar el nuevo campo y reducir drásticamente el costo de la consulta, ya que no tendrá que realizar la concatenación en CADA fila cada vez que ejecuta la consulta. El beneficio de esto dependerá de algunas cosas (por ejemplo, cuántas filas, con qué frecuencia se actualizan las filas, etc.), pero juegue con EXPLICAR las consultas y vea si puede ahorrar costos de esa manera. –

Cuestiones relacionadas