SQL Performance


Aunque no soy ni mucho menos un profesional de SQL, tengo que admitir que es uno de los lenguajes que más me gustan (y cada día me siento más cómodo con él). Lo mejor del asunto es que no sé porqué me gusta; probablemente sea porque escribiendo bien poco, parece que estés haciendo cosas de genio :) .

Uno de los temas más interesantes de SQL es el rendimiento: un mundo a explorar por muchos de nosotros.

Generalmente, cuando nos percatamos de lentitud en el sistema, e identificamos al SGBD (en mi caso MySQL) como posible culpable, lo primero que hacemos es pensar: “Puto MySQL, si tuviera un Oracle haría maravillas”. Al menos eso pensaba yo casi siempre… Pero claro, nunca nos paramos a mirarnos en el espejo. La culpa siempre es de otro/s (“todos somos inocentes hasta que se demuestre lo contrario”).

Hoy he estado revisando las SQL que hace apenas un año entregué en el proyecto de final de carrera, y me he reído un buen rato. Incluso he pensado en entregarme a la policía por hacer sufrir de esa forma tan atroz al servidor de BBDD.

Llevo un año trabajando con bases de datos diariamente, tocando SQL Server y MySQL principalmente. Y he aprendido una barbaridad. Pero no sólo a hacer SQLs, sino a hacer SQLs “como Dios manda”.

He leído mucho, he visto SQLs hechas por cracks del lenguaje, he trasteado… Y sigo llegando a la misma conclusión: por muy profesional que seas, siempre hay una SQL más eficiente que la tuya, y que hace lo mismo.

Así que ya no me doy de hostias cuando me doy cuenta de que la performance de mi SQL es mejorable; simplemente lo aprendo, lo asimilo y trato de no cometer el mismo error la próxima vez.

Y bueno, ya que tengo el blog (y no tengo muchas otras cosas que contar), me gustaría compartir mis experiencias con SQL, en busca de ayudar a aquellos que están en una situación algo retrasada respecto a lo que yo pueda saber, y también en busca de opiniones de gente que se ríe de lo que escribo :) .

Y el primer tip será… Trrrrrrtrrrrtrrtrr… UNION VS UNION ALL.

Hace un par de días, tuve un problema con una SQL que hacía múltiples UNION; sin él, una de las consultas devolvía más de mil registros, pero haciéndolo, el result set era de 500 filas… ¿Cómo puede ser?

Googleando un poco, leí que UNION hace un DISTINCT de cada SQL que lo conforma, eliminando las duplicidades. Sinceramente, no lo sabía.

Si quieres mantener los registros duplicados, hay que hacer un UNION ALL entre las SQL.

Es entonces cuando me asaltaron las dudas: ¿Es UNION ALL más rápido que UNION? Si palabras como EXCEPT, JOIN, CROSS, SUBQUERY… suenan a lento, imagínate la expresión UNION ALL. No tiene pinta de ser precisamente rápido.

Pero como buen informático, me dispongo a despejar mis dudas, y a hacer pruebas de rendimiento. La consulta es bien sencilla:

SELECT id FROM tabla1 UNION SELECT id FROM tabla2
SELECT id FROM tabla1 UNION ALL SELECT id FROM tabla2

Mi mente vaticinaba que UNION ALL tiene que ser más rápido al no hacer DISTINCT; pero claro, la nomenclatura dice que UNION ALL es muuuuucho más lento que UNION (básicamente por el ALL).

Pues esta vez gana la lógica: ¡¡ UNION ALL es 6 veces más rápido que UNION !!. En el ejemplo (ambas tablas con 500.000 de registros), los resultados fueron (media aritmética de 10 pruebas):

  • UNION: 24.1252 segundos
  • UNION ALL: 3.9918 segundos

Moraleja: siempre que sepas de antemano que no existirán registros duplicados, usa UNION ALL.




PHP es… Inocente


Siempre que hay tertulias informáticas “frikis” (que nadie se ofenda por la expresión) aparece el tema estrella; un tema que siempre está ahí, candente, maquinando su próxima aparición, la próxima disputa…

Hace apenas unos días tuvo que aparecer el tema; pensaba que no era el día, pero hizo acto de presencia (como siempre): “PHP es una mierda“.

Y claro, yo que soy un acérrimo defensor de PHP (como si fuera mi hijo), pues no dejo pasar esas palabras en vano, y allí es cuando la cago de verdad (me pongo nervioso sin querer), porque doy pie a la gran discusión: ¿Es PHP un lenguaje para desarrollar de forma profesional?

Mucha gente piensa que no, y es posible que tengan razón… Si aglutinamos todas las funciones que tiene PHP y las ponemos en una tira, probablemente nos crezca la barba (y aún no habremos acabado de leerlas). Por tanto, es cierto que PHP parece un lenguaje creado a partir de un conjunto de funciones (y cuantas más, mejor), muchas de ellas con funcionalidades más que dudosas.

Para más inri, muchas de las funciones no siguen un patrón definido en lo que a parámetros se refiere (y al final vas a parar a la documentación, o rezas para que el IDE te lo complete automáticamente como Dios manda). Un ejemplo gracioso: tenemos isset, pero is_null… ¿Nos aclaramos? :S

Además, es que es tan sumamente tentador y rápido el spaghetti code

Vale, quizás Java sea un lenguaje mucho más limpio, más estructurado, y que obliga al programador a “programar bien”. Desde luego, no seré yo quien entre a valorar esas afirmaciones (básicamente, porque no sería justo que opinara de algo que no sé…).

Y puede que Python sea un lenguaje que permite al programador ser más productivo, que al fin y al cabo es lo que importa. Unido esto al trace que te permite hacer Python…

También es cierto que el futuro parece que se decanta por RIA, y un servidor “atontao” (sin importar si detrás hay PHP o PericoDeLosPalotes).

Tanto pensar me va a sentar mal… Me estoy empezando a agobiar. Así que me haré la pregunta: ¿PHP tiene futuro, o caerá como han hecho otros lenguajes que parecían inmortales?

Pues mi opinión (ojo, 100% subjetiva) es que PHP es el mejor lenguaje EN SU ÁMBITO DE APLICACIÓN. Si tengo que hacer una aplicación de escritorio, no usaré PHP (qué aberración), pero desde luego que si es una aplicación web, lo primero en lo que pensaré es en PHP, por encima del resto.

¿Qué lenguaje de programación web tiene tanta documentación, recursos, clases? ¿Qué lenguaje tiene tanta comunidad detrás? ¿Qué porcentaje de las webs que visitamos diariamente nos las sirve nuestro querido LAMP? ¿Qué lenguaje puede presumir de ser más rápido versión a versión?

De hecho, me atrevo a decir que PHP está viviendo un momento muy dulce, con grandes cambios internos (véase PHP 5.3 y 5.4). Unas cuantas reflexiones más y acabamos.

Mucha gente dice también que PHP es sucio y feo de ver; pues a esa gente le pregunto: ¿habéis visto Symfony ó Zend Framework por dentro? (a mí me ha tocado por “culpa” de XDebug). Eso es poesía hecha código.

La penúltima pregunta (a modo de reflexión): ¿es todo culpa del lenguaje, o somos los programadores quienes caemos en la tentación de hacer las cosas mal?

Y respondo a la pregunta más importante: ¿qué lenguaje es el “chulo” que pretende quitarle el trono a PHP?. No nos engañemos: NINGUNO.




Motores de plantillas en PHP


Sin duda, uno de los temas que siempre me han interesado es el uso o no de motores de plantillas en PHP. ¿Realmente sirven para algo, o son una “moda pasajera”? ¿Hasta qué punto afectan al rendimiento de una aplicación web?

De todas formas, hay tanta variedad donde elegir (Smarty, PHPTal, Dwoo, Calypso, Twig, Haanga…) que muchas veces elegir una u otra parece más un juego de azar que una decisión técnica.

Hasta hace un tiempo (cuando digo “hace un tiempo”, es hace más de un año) usaba Smarty. No podía quejarme: cumple con su funcionalidad con creces, tiene una comunidad enorme detrás… Pero Smarty es otro lenguaje de programación, que pasa a unirse a mi particular fiesta: HTML, CSS, JS, PHP… y ahora Smarty.

Conclusión: demasiado complejo para lo que realmente necesitaba. Las dudas “me atormentaban”, así que decidí buscar información sobre otros motores de plantillas; pocas búsquedas en San Google me bastaron para sentenciar: “Los motores de plantillas son una mierda. No sirven para nada. PHP es un buen lenguaje de plantillas. Rápido y limpio.“.

Pero apenas dos meses después, aún con rencor hacia Smarty y los motores de plantillas, leí un post acerca de Haanga, un motor de plantillas Django way. Me enamoré de su sintaxis. Y para colmo, ¡eficiente!

Lo he usado en diversos proyectos, y tengo que decir que estoy muy contento. Es una maravilla de sistema de plantillas.

Cambiando de tercio, el proyecto Symfony está impulsando fuertemente Twig, un sistema de plantillas creado por Fabien Potencier (un auténtico máquina). Teniendo en cuenta lo bueno que es Symfony, ¿cómo no lo va a ser Twig?

No le hice demasiado caso, hasta que me tocó hacer un proyecto en Symfony2, donde te “recomiendan” usar Twig como motor de plantillas de las views. ¿Conclusión? ¡La sintaxis es igual que la de Haanga! ¡Son igual de buenos!

He integrado Twig en mis proyectos siguientes, con otros frameworks PHP, como Codeigniter, Zend Framework… Y ahora lo estoy probando con FuelPHP.

Pero… me pica la curiosidad por saber realmente cuál es mejor. Como en sintaxis son muy parecidos, me centro en aspectos de rendimiento.

Los dos “se venden” como motores muy rápidos:

  • Haanga: über efficient template engine for PHP
  • Twig: The flexible, fast, and secure template engine for PHP

Para comparar el rendimiento, haremos algo básico, pero típico en cualquier página web: un layout básico con herencia de plantillas de primer nivel. Cierto es que una prueba más realista hubiera sido creando un sistema con dos niveles, pero bueno… Mi intención es simplemente hacer pruebas base; si alguien quiere hacer pruebas más exhaustivas, le paso el código y que lo complete :) .

Y haremos una prueba cargando 100 registros. Además, inyectamos el valor del título, los puntos de menú…

Básicamente, el array a cargar será el siguiente:

$languages = array	(
	array(
		'name'		=> 'PHP',
		'created_date'	=> '1994',
		'created_by' 	=> 'Rasmus Lerdorf'
	),
	array(
		'name' 		=> 'Javascript',
		'created_date' 	=> '1995',
		'created_by'	=> 'Netscape'
	),
	array(
		'name' 		=> 'Java',
		'created_date' 	=> '1995',
		'created_by' 	=> 'Sun Microsystems'
	),
	array(
		'name' 		=> 'C',
		'created_date' 	=> '1972',
		'created_by' 	=> 'Dennis Ritchie'
	),
	array(
		'name' 		=> 'C++',
		'created_date' 	=> '1980',
		'created_by' 	=> 'Bjarne Stroustrup'
	),
	array(
		'name' 		=> 'Python',
		'created_date' 	=> '1991',
		'created_by' 	=> 'Guido van Rossum'),
	array(
		'name'		=> 'Lisp',
		'created_date' 	=> '1958',
		'created_by' 	=> 'John McCarthy'
	),
	array(
		'name'		=> 'C#',
		'created_date' 	=> '2001',
		'created_by' 	=> 'Microsoft'
	),
	array(
		'name' 		=> 'Ruby',
		'created_date' 	=> '1995',
		'created_by' 	=> 'Yukihiro "Matz" Matsumoto'
	),
	array(
		'name' 		=> 'Objective-C',
		'created_date' 	=> '1980',
		'created_by' 	=> 'Brad Cox'
	), ...
);

$menu = array(
	array(
		'href'		=> '',
		'content'	=> 'Inicio',
		'selected'	=> 'si'
	),
	array(
		'href'		=> 'sobre-mi',
		'content'	=> 'Sobre mí',
		'selected'	=> 'no'
	),
	array(
		'href'		=> 'contacto',
		'content'	=> 'Contacto',
		'selected'	=> 'no'
	)
);

$result = array(
	'title'		=> 'Haanga VS Twig',
	'header'	=> 'Haanga VS Twig',
	'menu'		=> $menu,
	'lenguajes'	=> $languages,
);

En todo momento mediremos el tiempo y la cantidad de memoria consumida. Sé que no son pruebas demasiado exhaustivas, pero sirven para conocer el rendimiento base de ambos motores (no me gustan los benchmarks con 100000 de registros, básicamente porque no son realistas).

Bueno, como estoy alargando demasiado el post, veamos los resultados:

Memoria (MB) Tiempo (s)
Haanga 0.041339874267578 0.0023729801177979
Twig 0.0940419921875 0.005030181884766

¡Vaya! Twig requiere más del doble de memoria, y el tiempo de parseo también duplica a Hangaa.

Los resultados son, evidentemente, con las plantillas ya compiladas. Veo inútil hacer comparativas de tiempo de compilación…

Pienso que la comparativa ha sido muy justa, pues ambos motores escapan las variables, y las pruebas se han realizado bajo las mismas condiciones.

Pero entonces… si estoy utilizando Twig “¿me paso a Haanga?“.

Bueno, pues no (o sí, eres libre). Esto es una simple comparativa de rendimiento, en la que se demuestra que realmente Haanga es ultraeficiente. Y doy fe porque lo he usado en diversos proyectos.

Pero Twig también es muy eficiente, la sintaxis es maravillosa (a mi modo de ver, claro :D ), la documentación excelente (algo en lo que Haanga flaquea, y mucho), y la comunidad detrás empuja el proyecto a un ritmo contra el que Haanga simplemente no puede hacer frente.




¿Cuál es el mejor framework PHP?


Aunque todos hemos empezado programando raw PHP, tarde o temprano nos interesamos por hacer las cosas mejor. Se trata, como digo, de un sentimiento que tarde o temprano surge. Una sensación de que queremos mejorar, y hacer las cosas como Dios manda.

Yo tuve esa sensación hace algo más de dos años, cuando tuve que crear una aplicación web de un tamaño considerable. Tenía unos 19 años, poca experiencia, pero muchas ganas (lo de las ganas aún no lo he perdido, que conste).

Disponía ya de una serie de librerías que me ayudaban bastante en el desarrollo web, como un query builder de lo más basicote, un parser RSS propio (utilizando por debajo MagpieRSS), una clase de autenticación y autorización ultrasencillas… Ahora que lo pienso, me servían bastante, y el desarrollo era agile total…

Pero te paras a pensar: “¿Quién sabe utilizar éstas librerías?“. Pues yo… sólo yo, y nada más que yo…

Vale, pero “¿Están probadas?“. Pues supongo que sí, porque las he probado y nunca han fallado (entonces no sabía ni qué era el Unit Testing).

Y “¿Tus aplicaciones son escalables?“. Mmmm… supongo (en ese momento me creía que lo sabía todo sobre PHP).

Básicamente, términos que no conocía como DRY (Don’t Repeat Yourself) ó Don’t Reinvent the Wheel estaban “llamando a mi puerta”, y yo les daba paso :D .

No sé exactamente porqué, estas preguntas me inquietaban mucho, así que decidí indagar. Una simple búsqueda en Google: “programación avanzada php” me sirvió… Esa ineficaz búsqueda fue suficiente. Google me lo estaba diciendo por todas partes: FRAMEWORK.

Me quedé perplejo, atónito… “¿De qué coño habla esto?“, pensé. Entonces decidí cambiar mi búsqueda: “frameworks php“. Más de 14.000.000 de resultados me estaban gritando: “Tú, paleto, cambia tu forma de trabajar YA“.

Hasta la versión 4, PHP era un lenguaje anti-framework (no es el momento de explicar porqué), pero desde PHP5, el lenguaje ha adquirido la madurez necesaria para considerar el lanzamiento de frameworks (básicamente, gracias a la orientación a objetos). Y así fue: el boom de los frameworks llegó (Symfony, Zend, Cake, Yii, Codeigniter…). Todos ellos siguiendo el camino iniciado por los inseparables Ruby y OnRails (atención, el primero de ellos es un lenguaje, y el segundo es el framework).

Desde entonces se inició la típica guerra Windows VS Linux… Pero en este caso, había muchos contendientes (demasiados, quizás): Symfony VS Zend, Codeigniter VS CakePHP, Yii VS Zend… Y todas las posibilidades habidas y por haber.

Tanta guerra al final nos deja con DOS grandes preguntas:

  • Vale, pero… ¿Qué framework uso?
  • Y la pregunta que todos nos hacemos: “¿Cuál es el mejor?

Si esperáis encontrar la solución a vuestros rezos aquí, váis apañaos. A las dos preguntas contestaré de forma neutra, pero más adelante, que tengo que seguir con mi intrigante historia.

Teniendo en cuenta el lío que tenía encima, decidí preguntar en un foro, donde me contestaron: “¡Para empezar usa Codeigniter!“. Y creí ciegamente en las respuestas que me dieron.

He usado CI en diversos proyectos, he usado Symfony2 en un proyecto, Zend Framework en otro y Yii en uno personal. Y ahora tengo un proyecto con FuelPHP (un framework que podríamos definir como “el Codeigniter de PHP 5.3″).

Tras mis experiencias con los frameworks de PHP, tengo que decir que cuando usas uno, hechas en falta características del otro… y viceversa. No considero que uno sea mejor que otro; simplemente cada uno tiene una forma de hacer las cosas, y unas soluciones a los problemas que se plantean en el desarrollo web.

Entonces, 

  • Respuesta a la pregunta 1: Depende, cada uno tiene su ámbito de aplicación (casi todos lo tienen).
  • Respuesta a la pregunta 2: Con el que desarrolles más rápido, que tenga buena documentación, y una comunidad grande detrás.
¿Soy un mentiroso porque os he prometido daros la respuesta, y no lo he hecho? Pues no… La respuesta es la correcta. Dejemos de cegarnos por algo; no hay un mejor o un peor framework. Cada uno tiene sus ventajas e inconvenientes. La cuestión es que los desarrolladores hemos de ser lo suficientemente inteligentes como para ver cuál es el que nos conviene utilizar en cada proyecto.




Blog de Magd Kudama - Programación web