Rápida solución para problema de Perl.

Una entrada muy rápido esta vez. Yo tuve problemas para obtener el programa en Perl para usar el módulo DBI con Mysql. Seguí recibiendo este mensaje de error: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
Bueno, después de hacer un poco de búsqueda a través de google, he encontrado la respuesta. Mi base de datos está configurado en el servidor Apache, lo que significa que se encuentra archivo de socket mysqld en un lugar diferente. Para saber dónde está ubicado, ir a Mysql y ejecutar el siguiente comando:

Code:

show variables like 'socket%';


Parece que la ubicación en mi máquina es /opt/lampp/var/mysql/mysqld.sock
Así, entonces cambié mi origen de datos en la línea de conectar a la programa de Perl para leer:

Code:

$dsn = "DBI:mysql:$database:localhost:3306:mysql_socket=/opt/lampp/var/mysql/mysqld.sock";

Parece que es un obstáculo común, por lo que espero que esto ayuda a otros a continuar con su programación en Perl.

Más información sobre las variables.

Hola, yo pensé en hacer una pequeña adición a mi post anterior sobre las variables, ya que parece ser muy popular entre los lectores. En mi anterior entrada hablé principalmente de la utilización de las variables de sistema. Estos se establecen en el ámbito de tu período de sesiones utilizando Mysql - una vez que la conexión se termina la variable sale de ámbito de aplicación. Antes de ir a las variables globales, me gustaría mostrar el mejor uso que he visto recientemente de una variable de sesión. Se utiliza como alternativa a la función rownum, que está disponible en Oracle, pero no en Mysql. Aquí hay un ejemplo de esto en uso:

Code:

select @rownum:=@rownum+1 'row_num',
e.* from emp e,
(SELECT @rownum:=0) r
order by empno desc limit 5;


Con este código se evita la necesidad de escribir una primera línea que asigna un valor a la variable antes de ejecutar la consulta de Select, es decir SET @rownum := 0;


Ahora voy a escribir un poco sobre las variables de sistema, que son muy útiles para las personas que tratan de mejorar el rendimiento de su sesión de Mysql. Normalmente puedes ver el estado de estas variables utilizando el comando SHOW VARIABLES. Aunque las variables de sistema tienen valores por defecto, la mayoría de ellas pueden cambiarse en tiempo de ejecución usando el comando SET. Ver el enlace para ver mas sobre variables de sistema del servidor:

manual server system variables

También hay variables de estado del servidor. Estos existen en las conexiones, y se puede actualizarlas en el archivo de configuración my.cnf Normalmente puedes ver el estado de estas variables utilizando el sentencia SHOW STATUS. Por ejemplo, el valor contra el nombre Select_full_join muestra el número de Full-joins que no utilizan índices. Si ves aquí un alto valor indica la necesidad de hacer una mejor indexación de las tablas correspondientes. Ver el enlace para ver el manual sobre variables de estado del servidor:

Manual server-status-variables

Por cierto, aquí hay un enlace que da 10 variables de MySql que debes controlar.
techrepublic link (en ingles)

Las diez variables en el enlace anterior son:

Threads_connected -- El número de conexiones abiertas actualmente. Esto puede ayudar en el análisis del tráfico o de decidir el mejor momento para un servidor de volver a empezar.


Created_tmp_disk_tables
-- El número de tablas temporales en disco creadas automáticamente por el servidor mientras ejecutaba sentencias. Acceso a tablas en disco es generalmente más lento que el acceso a las mismas tablas en la memoria. Por lo tanto, las consultas que utilizan la sintaxis CREATE TEMPORARY TABLE puedan ser lento cuando este valor es alto.

Handler_read_first -- El número de veces que se lee la primera entrada de un índice. Si MySQL haga con frecuencia el acceso a la primera fila de una tabla de índice, sugiere que se trata de realizar un escaneo secuencial de todo el índice. Esto indica que la tabla correspondiente no ha sido debidamente indizados.

Innodb_buffer_pool_wait_free -- Normalmente, las escrituras al buffer de InnoDB se llevan acabo en segundo plano. Aún así, si es necesario leer o crear una página y no existe ninguna página vacía disponible, entonces es también necesario esperar a que las páginas sean volcadas previamente. Este contador cuenta las instancias de estas esperas. Si el tamaño del buffer ha sido establecido correctamente, este valor debería ser pequeño.

Key_reads -- El número de lecturas físicas de un bloque de claves desde disco. Si Key_reads es grande, entonces el valor de key_buffer_size es, probablemente, demasiado pequeño.

Max_used_connections -- El número máximo de conexiones que han sido utilizadas simultáneamente desde que el servidor ha sido iniciado. Este valor ofrece un punto de referencia para ayudarle a decidir el número máximo de conexiones de su servidor debe apoyar.

Open_tables -- El número de tablas que han sido abiertas. Si Opened_tables es grande, probablemente el valor de table_cache es demasiado pequeño.

Select_full_join -- El número de joins que no utilizan índices. Si este valor no es 0, debería comprobar cuidadosamente los índices de sus tablas.

Slow_queries -- El número de consultas que han tardado más de long_query_time segundos. Un valor alto indica que el número de consultas no se ejecuta óptimamente. Un siguiente paso necesario sería examinar el log de consultas lentas e identificar estas consultas para la optimización.

Uptime -- El número de segundos que el servidor ha estado funcionando ininterrumpidamente

Recuerda que si estás buscando una variable específica a través de SHOW STATUS, siempre podriás utilizar la cláusula de LIKE por ejemplo:

Code:

show status like 'max%';


Bueno, como ya he dicho, es sólo una breve entrada esta vez.

Vuelvo

Thanks,
Mark

Hacer las consultas más eficiente (3) - La importancia de los índices

Se dice a menudo que la mala utilización de índices (o la falta de un índice) es la manera más rápida de matar a un sistema.
Un índice funciona por leer una lista de campos pre-clasificados para acceder a la consulta, en lugar de tener que realizar un gran ordenación en la memoria. Hay que recordar sin embargo que los índices vienen a un costo, principalmente en el uso de espacio de almacenamiento en disco (y también dificultan el proceso de actualización - INSERT, DELETE o UPDATE). Una cosa importante a tener en cuenta cuando haciendo la creación de un índice, es que es preferible reducir al mínimo el tamaño de los campos indexados. Un índice en un pequeño campo de tipo int es mucho mejor que un índice en un campo de tipo varchar(100). Si es necesario índice de un campo de tipo varchar, consideren la posibilidad de limitar el índice de los primeros caracteres, por ejemplo:

Code:

CREATE INDEX addr_line_indx ON members (addr_line1(15));


El índice general, funciona mejor cuando se usa la cláusula WHERE directamente con el campo por ejemplo WHERE col = 123 , o cuando se busca el maximo valor de la columna (MAX) o el mínimo valor de la columna (MIN). El índice también se puede utilizar para consultas de correspondencia con patron - la cláusula LIKE -, siempre que la comparación de cadenas no se inicia con un comodín (por ejemplo el signo de porcentaje). Así que, usando "WHERE campoA LIKE 'FARSC%'", se utilizará un índice en esta consulta, el siguiente no: "WHERE campoA LIKE '%FARSCAPE%'".
Para leer más sobre cómo MySQL usa índices (Lamentablemente esta sección todavía no se ha traducido al español):

mysql manual

Otro factor a considerar en poner un índice en un campo, es el de la selectividad. Si hay demasiados registros de datos del mismo valor (por ejemplo, si el campo registros de sexo, 'M' o 'F') luego Mysql le resultará más fácil para cargar todos los registros en la memoria y escanear a través de ellos, en lugar de utilizar el índice. La base de datos Mysql mantiene estadísticas sobre los índices de las tablas por lo que puede hacer una suposición en cuanto al momento de utilizar un índice o no. Por lo tanto, sólo tiene sentido utilizar los índices en los que el campo tiene un alto selectivty es decir, el conjunto de datos contiene su mayoría o totalidad valores únicos.

Una cosa para recordar en la creación de un índice que no tiene que limitarse a una sola columna. Por ejemplo, si se consulta a menudo en dos columnas Nombre y apellido, puede crear un multi-columna (o compuesto) índice:

Code:

CREATE INDEX name_idx ON members (apellido, nombre);

El orden de los componentes del índice es significativo. En este escenario, el índice sólo se utiliza en el campo nombre, cuando la cláusula WHERE incluye el campo apellido. Cuando las consultas sólo se especifican el campo nombre, un índice puede tener que ser creado. Además, si utiliza la cláusula de OR, el índice se ignora. Puedes leer más acerca de índices compuestos aquí

manual sobre multiple column

A veces, un índice no se utiliza en una consulta porque una función de conversión se lleva a cabo en el campo. Si puedes aislar un campo indexado en el lado izquierdo de la cláusula WHERE, puede persuadir a Mysql a utilizar el índice de la consulta

El mejor ejemplo de esto es algo que encontré en el libro Pro Mysql (Kruckenberg and Pipes):

Ejemplo de mala optimización:

Code:

SELECT * FROM customer_orders
WHERE TO_DAYS(pedido_alto) - TO_DAYS(NOW()) <= 7;

.
Buena optimización (el índice del campo pedido_alto se utilizará):

Code:

SELECT * FROM customer_orders
WHERE pedido_alto >= DATE_SUB(NOW(), INTERVAL 7 DAY);


Habrá casos en que sin embargo no se puede realizar una búsqueda de un campo sin necesidad de utilizar una función o transformación de este campo. En estos casos, si la consulta es necesario a menudo, puede ser más eficaz para crear una columna adicional que contiene el valor calculado de la columna.
Por ejemplo (de nuevo desde el libro ProMysql), la siguiente consulta SQL no va a utilizar un índice, incluso si existe en la columna EMAIL_ADDRESS

Code:

SELECT * FROM customers
WHERE email_address LIKE '%aol.com';


La solución para esto es crear una columna adicional que contiene el reverso de la dirección de correo electrónico y, a continuación, poner un índice sobre esta columna. Entonces podemos utilizar el índice a través de la siguiente consulta:

Code:

SELECT * FROM customers
WHERE email_address_reversed
  LIKE CONCAT(REVERSE('%aol.com'), '%');


Por supuesto, así como el espacio en disco adicional necesario para la columna adicional e índice, también tenemos que garantizar que el campo email_address_reversed se rellenará regularmente. Esto podría ser a través de la utilización de los disparadores en las inserciones y actualizaciones. O puede ejecutar una rutina de actualización de la tabla en intervalos regulares. Todo depende de la frecuencia con que necesitas para ejecutar la consulta de manera eficiente.

Una última cosa que pueden hacer sus consultas correr más rápido. Si la tabla ha tenido una gran cantidad de borra, inserciones y actualizaciones, puede ser un valor con el comando OPTIMIZE TABLE, por ejemplo

Code:

OPTIMIZE TABLE large_order_table;


Esto efectivamente es para reclamar el usuario no usado y para defragmentar el fichero de datos. También se mantiene el índice de las estadísticas actuales, que ayuda a MySQL a decidir cuándo usar un índice en una columna.

Saludos, Mark