Ya que ofreciste una recompensa, compartiré mis secretos ganados con tanto esfuerzo ...
En general, todos los SQL que sintonicé hoy requerían el uso de subconsultas. Habiendo venido del mundo de las bases de datos de Oracle, las cosas que daba por sentado no funcionaban igual con MySQL. Y mi lectura sobre el ajuste de MySQL me hace concluir que MySQL está detrás de Oracle en términos de optimización de consultas.
Si bien las consultas simples requeridas para la mayoría de las aplicaciones B2C pueden funcionar bien para MySQL, la mayoría de las consultas de informes agregados necesarias para Intelligence Reporting parecen requerir un poco de planificación y reorganización de las consultas SQL para guiar a MySQL a ejecutarlas más rápido.
Administración:
max_connections
es el número de conexiones simultáneas. El valor predeterminado es 100 conexiones (151 desde 5.0), muy pequeño.
Nota:
las conexiones ocupan memoria y es posible que su sistema operativo no pueda manejar muchas conexiones.
Los binarios de MySQL para Linux / x86 le permiten tener hasta 4096 conexiones concurrentes, pero los binarios autocompilados a menudo tienen un límite menor.
Configure table_cache para que coincida con el número de sus tablas abiertas y conexiones simultáneas. Observe el valor de open_tables y, si está creciendo rápidamente, deberá aumentar su tamaño.
Nota:
Los 2 parámetros anteriores pueden requerir muchos archivos abiertos. 20 + max_connections + table_cache * 2 es una buena estimación de lo que necesita. MySQL en Linux tiene una opción open_file_limit, establezca este límite.
Si tiene consultas complejas, es probable que sort_buffer_size y tmp_table_size sean muy importantes. Los valores dependerán de la complejidad de la consulta y los recursos disponibles, pero se recomiendan 4 Mb y 32 Mb, respectivamente, como puntos de partida.
Nota: Estos son valores "por conexión", entre read_buffer_size, read_rnd_buffer_size y algunos otros, lo que significa que este valor puede ser necesario para cada conexión. Por lo tanto, considere su carga y los recursos disponibles cuando configure estos parámetros. Por ejemplo, sort_buffer_size se asigna solo si MySQL necesita hacer una clasificación. Nota: tenga cuidado de no quedarse sin memoria.
Si tiene muchas conexiones establecidas (es decir, un sitio web sin conexiones persistentes), puede mejorar el rendimiento configurando thread_cache_size en un valor distinto de cero. 16 es un buen valor para empezar. Aumente el valor hasta que su threads_created no crezca muy rápidamente.
CLAVE PRIMARIA:
Solo puede haber una columna AUTO_INCREMENT por tabla, debe estar indexada y no puede tener un valor DEFAULT
CLAVE es normalmente un sinónimo de ÍNDICE. El atributo de clave PRIMARY KEY también se puede especificar como solo KEY cuando se proporciona en una definición de columna. Esto se implementó por compatibilidad con otros sistemas de bases de datos.
UNA CLAVE PRIMARIA es un índice único en el que todas las columnas de clave deben definirse como NO NULAS
Si un índice PRIMARY KEY o UNIQUE consta de una sola columna que tiene un tipo entero, también puede hacer referencia a la columna como "_rowid" en las sentencias SELECT.
En MySQL, el nombre de una PRIMARY KEY es PRIMARY
Actualmente, solo las tablas InnoDB (v5.1?) Admiten claves externas.
Por lo general, crea todos los índices que necesita cuando crea tablas. Se indexará cualquier columna declarada como PRIMARY KEY, KEY, UNIQUE o INDEX.
NULL significa "no tener un valor". Para probar NULL, no puede usar los operadores de comparación aritmética como =, <o <>. En su lugar, utilice los operadores IS NULL y IS NOT NULL:
NO_AUTO_VALUE_ON_ZERO suprime el incremento automático para 0 de modo que solo NULL genera el siguiente número de secuencia. Este modo puede resultar útil si se ha almacenado 0 en la columna AUTO_INCREMENT de una tabla. (Por cierto, almacenar 0 no es una práctica recomendada).
Para cambiar el valor del contador AUTO_INCREMENT que se utilizará para nuevas filas:
ALTER TABLE mytable AUTO_INCREMENT = value;
o SET INSERT_ID = valor;
A menos que se especifique lo contrario, el valor comenzará con: 1000000 o especificarlo así:
...) ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 1
HORARIOS:
Los valores de las columnas TIMESTAMP se convierten de la zona horaria actual a UTC para el almacenamiento y de UTC a la zona horaria actual para su recuperación.
http://dev.mysql.com/doc/refman/5.1/en/timestamp.html
Para una columna TIMESTAMP en una tabla, puede asignar la marca de tiempo actual como el valor predeterminado y el valor de actualización automática.
Una cosa a tener en cuenta cuando se usa uno de estos tipos en una cláusula WHERE, es mejor hacer WHERE datecolumn = FROM_UNIXTIME (1057941242) y no WHERE UNIX_TIMESTAMP (datecolumn) = 1057941242. hacer esto último no aprovechará un índice en esa columna.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
UNIX_TIMESTAMP()
FROM_UNIXTIME()
UTC_DATE()
UTC_TIME()
UTC_TIMESTAMP()
si convierte una fecha y hora a una marca de tiempo unix en MySQL:
Y luego agregue 24 horas:
Y luego vuelva a convertirla en una fecha y hora, ¡mágicamente pierde una hora!
Esto es lo que está pasando. Al convertir la marca de tiempo de Unix a una fecha y hora, la zona horaria se toma en consideración y da la casualidad de que entre el 28 y el 29 de octubre de 2006 salimos del horario de verano y perdimos una hora.
A partir de MySQL 4.1.3, las funciones CURRENT_TIMESTAMP (), CURRENT_TIME (), CURRENT_DATE () y FROM_UNIXTIME () devuelven valores en la zona horaria actual de la conexión , que está disponible como el valor de la variable de sistema time_zone. Además, UNIX_TIMESTAMP () asume que su argumento es un valor de fecha y hora en la zona horaria actual.
La configuración de la zona horaria actual no afecta a los valores mostrados por funciones como UTC_TIMESTAMP () o valores en las columnas DATE, TIME o DATETIME.
NOTA: ON UPDATE ONLY actualiza la fecha y hora si se cambia un campo. Si una ACTUALIZACIÓN da como resultado que no se cambien los campos, la fecha y hora NO se actualiza.
Además, el primer TIMESTAMP siempre es AUTOUPDATE de forma predeterminada, incluso si no se especifica
Cuando trabajo con fechas, casi siempre me convierto en fecha juliana porque la matemática de datos es una simple cuestión de sumar o restar números enteros y segundos desde medianoche por la misma razón. Es raro que necesite una resolución de tiempo de granularidad más fina que segundos.
Ambos se pueden almacenar como un entero de 4 bytes, y si el espacio es realmente reducido se pueden combinar en el tiempo de UNIX (segundos desde la época 1/1/1970) como un entero sin signo que será válido hasta alrededor de 2106 como:
'segundos en 24 horas = 86400
'Signed Integer max val = 2,147,483,647 - puede contener 68 años de Segundos
'Entero sin signo max val = 4.294.967.295 - puede contener 136 años de Segundos
Protocolo binario:
MySQL 4.1 introdujo un protocolo binario que permite enviar y devolver valores de datos que no son cadenas en formato nativo sin conversión hacia y desde el formato de cadena. (Muy útil)
Aparte, mysql_real_query () es más rápido que mysql_query () porque no llama a strlen () para operar en la cadena de instrucciones.
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
El protocolo binario admite declaraciones preparadas del lado del servidor y permite la transmisión de valores de datos en formato nativo. El protocolo binario se sometió a bastante revisión durante las versiones anteriores de MySQL 4.1.
Puede utilizar la macro IS_NUM () para probar si un campo tiene un tipo numérico. Pase el valor del tipo a IS_NUM () y se evalúa como TRUE si el campo es numérico:
Una cosa a tener en cuenta es que los datos binarios PUEDEN enviarse dentro de una consulta normal si la escapas y recuerdas que MySQL solo requiere que la barra invertida y el carácter de comillas se escapen . Entonces, esa es una manera realmente fácil de INSERTAR cadenas binarias más cortas, como contraseñas cifradas / saladas, por ejemplo.
Servidor maestro:
http://www.experts-exchange.com/Database/MySQL/Q_22967482.html
http://www.databasejournal.com/features/mysql/article.php/10897_3355201_2
CONCESIÓN DE REPLICACIÓN ESCLAVO ENCENDIDO . a slave_user IDENTIFICADO POR 'slave_password'
#Master Binary Logging Config STATEMENT causes replication
to be statement-based - default
log-bin=Mike
binlog-format=STATEMENT
server-id=1
max_binlog_size = 10M
expire_logs_days = 120
#Slave Config
master-host=master-hostname
master-user=slave-user
master-password=slave-password
server-id=2
El archivo de registro binario debe leer:
http://dev.mysql.com/doc/refman/5.0/en/binary-log.html
http://www.mydigitallife.info/2007/10/06/how-to-read-mysql-binary-log-files-binlog-with-mysqlbinlog/
http://dev.mysql.com/doc/refman/5.1/en/mysqlbinlog.html
http://dev.mysql.com/doc/refman/5.0/en/binary-log.html
http://dev.mysql.com/doc/refman/5.1/en/binary-log-setting.html
Puede eliminar todos los archivos de registro binarios con la instrucción RESET MASTER, o un subconjunto de ellos con PURGE MASTER
--result-file = binlog.txt TrustedFriend-bin.000030
Normalización:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
Funciones UDF
http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx
http://souptonuts.sourceforge.net/readme_mysql.htm
Tipos de datos:
http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html
http://www.informit.com/articles/article.aspx?p=1238838&seqNum=2
http://bitfilm.net/2008/03/24/saving-bytes-efficient-data-storage-mysql-part-1/
Una cosa a tener en cuenta es que en una tabla mixta con CHAR y VARCHAR, mySQL cambiará los CHAR a VARCHAR
RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (RecNum)
MySQL siempre representa las fechas con el año primero, de acuerdo con las especificaciones estándar SQL e ISO 8601
Misc:
Desactivar algunas funciones de MySQl dará como resultado archivos de datos más pequeños y un acceso más rápido. Por ejemplo:
--datadir especificará el directorio de datos y
--skip-innodb desactivará la opción inno y te ahorrará entre 10 y 20 millones
Más aquí
http://dev.mysql.com/tech-resources/articles/mysql-c-api.html
Descargar Capítulo 7 - Gratis
InnoDB es transaccional, pero conlleva una sobrecarga de rendimiento. He encontrado que las tablas MyISAM son suficientes para el 90% de mis proyectos. Las tablas no seguras para transacciones (MyISAM) tienen varias ventajas propias, todas las cuales ocurren porque:
no hay gastos generales de transacción:
Mucho mas rápido
Menores requisitos de espacio en disco
Se requiere menos memoria para realizar actualizaciones
Cada tabla MyISAM se almacena en el disco en tres archivos. Los archivos tienen nombres que comienzan con el nombre de la tabla y tienen una extensión para indicar el tipo de archivo. Un archivo .frm almacena el formato de la tabla. El archivo de datos tiene una extensión .MYD (MYData). El archivo de índice tiene una extensión .MYI (MYIndex).
Estos archivos se pueden copiar en una ubicación de almacenamiento intactos sin utilizar la función de copia de seguridad de administradores de MySQL, que consume mucho tiempo (también lo es la restauración)
El truco es hacer una copia de estos archivos y luego SUJETAR la mesa. Cuando vuelva a colocar los archivos, MySQl los reconocerá y actualizará el seguimiento de la tabla.
Si debe hacer una copia de seguridad / restaurar,
Restaurar una copia de seguridad o importar desde un archivo de volcado existente puede llevar mucho tiempo dependiendo de la cantidad de índices y claves primarias que tenga en cada tabla. Puede acelerar este proceso drásticamente modificando su archivo de volcado original rodeándolo con lo siguiente:
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;
.. your dump file ..
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;
Para aumentar enormemente la velocidad de recarga, agregue el comando SQL SET AUTOCOMMIT = 0; al principio del archivo de volcado y agregue COMMIT; comando hasta el final.
De forma predeterminada, la confirmación automática está activada, lo que significa que todos y cada uno de los comandos de inserción en el archivo de volcado se tratarán como una transacción separada y se escribirán en el disco antes de que se inicie el siguiente. Si no agrega estos comandos, volver a cargar una base de datos grande en InnoDB puede llevar muchas horas ...
El tamaño máximo de una fila en una tabla MySQL es 65,535 bytes
La longitud máxima efectiva de un VARCHAR en MySQL 5.0.3 y en = tamaño máximo de fila (65,535 bytes)
Los valores VARCHAR no se rellenan cuando se almacenan. Los espacios finales se conservan cuando los valores se almacenan y recuperan, de conformidad con SQL estándar.
Los valores CHAR y VARCHAR en MySQL se comparan sin tener en cuenta los espacios finales.
El uso de CHAR solo acelerará su acceso si todo el registro tiene un tamaño fijo. Es decir, si usa cualquier objeto de tamaño variable, también puede hacer que todos sean de tamaño variable. No gana velocidad al usar un CHAR en una tabla que también contiene un VARCHAR.
El límite de VARCHAR de 255 caracteres se elevó a 65535 caracteres a partir de MySQL 5.0.3
Las búsquedas de texto completo solo son compatibles con tablas MyISAM.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Las columnas BLOB no tienen juego de caracteres y la clasificación y la comparación se basan en los valores numéricos de los bytes en los valores de las columnas.
Si el modo SQL estricto no está habilitado y asigna un valor a una columna BLOB o TEXT que excede la longitud máxima de la columna, el valor se trunca para ajustarse y se genera una advertencia.
Comandos útiles:
comprobar el modo estricto: SELECT @@ global.sql_mode;
desactivar el modo estricto:
SET @@ global.sql_mode = '';
SET @@ global.sql_mode = 'MYSQL40'
o eliminar: sql-mode = "STRICT_TRANS_TABLES, ...
MOSTRAR COLUMNAS DE mytable
SELECCIONE max (namecount) COMO virtualcolumn
DE mytable ORDENE POR virtualcolumn
http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-fields.html
http://dev.mysql.com/doc/refman/5.1/en/information-functions.html#function_last-insert-id
last_insert_id ()
obtiene el PK de la última fila insertada en el hilo actual max (pkcolname) obtiene el último PK en general.
Nota: si la tabla está vacía, max (pkcolname) devuelve 1 mysql_insert_id () convierte el tipo de retorno de la función nativa de la API de MySQL C mysql_insert_id () a un tipo de largo (llamado int en PHP).
Si su columna AUTO_INCREMENT tiene un tipo de columna de BIGINT, el valor devuelto por mysql_insert_id () será incorrecto. En su lugar, utilice la función SQL interna de MySQL LAST_INSERT_ID () en una consulta SQL.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
Solo una nota que cuando intentas insertar datos en una tabla y obtienes el error:
Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’
usando algo como
INSERT INTO table (this, that) VALUES ($this, $that)
es porque no tiene apóstrofos alrededor de los valores que está tratando de incluir en la tabla. Entonces deberías cambiar tu código a:
INSERT INTO table (this, that) VALUES ('$this', '$that')
recordatorio de que `` se utilizan para definir campos, bases de datos o tablas de MySQL, no valores;)
Conexión perdida al servidor durante la consulta:
http://dev.mysql.com/doc/refman/5.1/en/gone-away.html
http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html
http://dev.mysql.com/doc/refman/5.0/en/server-parameters.html
http://dev.mysql.com/doc/refman/5.1/en/show-variables.html
http://dev.mysql.com/doc/refman/5.1/en/option-files.html
http://dev.mysql.com/doc/refman/5.1/en/error-log.html
Consultas de ajuste
http://www.artfulsoftware.com/infotree/queries.php?&bw=1313
Bueno, creo que eso debería ser suficiente para ganar el bono ... Los frutos de muchas horas y muchos proyectos con una gran base de datos gratuita . Desarrollo servidores de datos de aplicaciones en plataformas Windows principalmente con MySQL. El peor lío que tuve que arreglar fue
La última pesadilla de base de datos heredada de MySQL
Esto requirió una serie de aplicaciones para procesar las tablas en algo útil usando muchos de los trucos mencionados aquí.
Si encontró esto sorprendentemente útil, exprese su agradecimiento votando hacia arriba.
Consulte también mis otros artículos y documentos técnicos en: www.coastrd.com
SET SESSION sql_mode='ANSI';
Un comando para averiguar qué tablas están actualmente en la caché:
(Del blog de rendimiento de MySQL )
fuente
Un comando para averiguar quién está haciendo qué:
Y puede matar un proceso con:
fuente
En particular, me gusta el soporte integrado de MySQL para
inet_ntoa()
yinet_aton()
. Hace que el manejo de direcciones IP en tablas sea muy sencillo (¡al menos siempre que sean solo direcciones IPv4!)fuente
Me encanta
on duplicate key
(AKA upsert, merge) para todo tipo de contadores creados de forma perezosa:Puede insertar muchas filas en una consulta y manejar inmediatamente el índice duplicado para cada una de las filas.
fuente
Nuevamente, no características realmente ocultas, pero sí muy útiles:
Característica
Agarre fácilmente DDL:
SHOW CREATE TABLE CountryLanguage
salida:
Característica: función agregada GROUP_CONCAT () Crea una cadena concatenada de sus argumentos por detalle, y los agrega concatenando aquellos por grupo.
Ejemplo 1: simple
Salida:
Ejemplo 2: múltiples argumentos
Salida:
Ejemplo 3: uso de un separador personalizado
Salida:
Ejemplo 4: controlar el orden de los elementos de la lista
Salida:
Característica: COUNT (DISTINCT) con múltiples expresiones
Puede utilizar varias expresiones en una expresión COUNT (DISTINCT ...) para contar el número de combinaciones.
SELECT COUNT(DISTINCT CountryCode, Language) FROM CountryLanguage
Característica / Gotcha: No es necesario incluir expresiones no agregadas en la lista GROUP BY
La mayoría de RDBMS-es imponen un GROUP BY compatible con SQL92 que requiere que todas las expresiones no agregadas en la lista SELECT aparezcan en GROUP BY. En estos RDBMS-es, esta declaración:
no es válido, porque la lista SELECT contiene la columna no agregada Country.Continent que no aparece en la lista GROUP BY. En estos RDBMS-es, debe modificar la lista GROUP BY para leer
o debe agregar algún agregado sin sentido a Country.Continent, por ejemplo
Ahora bien, es que lógicamente no hay nada que exija que País.Continente se agregue. Consulte, Country.Code es la clave principal de la tabla Country. Country.Continent también es una columna de la tabla Country y, por lo tanto, por definiciones depende funcionalmente de la clave principal Country.Code. Por lo tanto, debe existir exactamente un valor en Country.Continent para cada Country.Code distinto. Si te das cuenta de eso, entonces te das cuenta de que no tiene sentido agregarlo (solo hay un valor, correcto) ni agrupar por él (ya que no hará que el resultado sea más único ya que ya estás agrupando por el pk)
De todos modos, MySQL le permite incluir columnas no agregadas en la lista SELECT sin necesidad de que las agregue también a la cláusula GROUP BY.
El problema con esto es que MySQL no lo protege en caso de que use una columna no agregada. Entonces, una consulta como esta:
Se ejecutará sin quejas, pero la columna CountryLanguage.Percentage contendrá porcentajes sin sentido (es decir, de todos los porcentajes de idiomas, uno de los valores disponibles para el porcentaje se elegirá al azar o al menos fuera de tu control.
Ver: Grupo de desacreditación por mitos
fuente
El comando "pager" en el cliente
Si tiene, digamos, 10,000 filas en su resultado y desea verlas (esto asume los comandos "less" y "tee" disponibles, que normalmente es el caso en Linux; en Windows YMMV).
Y los obtendrá en el visor de archivos "menos" para que pueda hojearlos, buscar, etc.
también
Escribirá cómodamente en un archivo.
fuente
Algunas cosas que pueden resultarle interesantes:
fuente
No es una característica oculta, pero útil de todos modos: http://mtop.sourceforge.net/
fuente
Estos son algunos de mis consejos: escribí sobre ellos en mi blog ( Enlace )
fuente
Si va a trabajar con bases de datos InnoDb de transacciones grandes y / o de alto volumen, aprenda y comprenda el blog de rendimiento de Mysql "MOSTRAR ESTADO DE INNODB" , se convertirá en su amigo.
fuente
Si usa cmdline Mysq, puede interactuar con la línea de comandos (en máquinas Linux, no estoy seguro de si hay un efecto equivalente en Windows) usando el grito / signo de exclamación. Por ejemplo:
mostrará el código para file1.sql. Para guardar su declaración y consulta en un archivo, use la función de tee
para apagar esto use \ t
Por último, para ejecutar un script que ya ha guardado, utilice "nombre de archivo de origen". Por supuesto, la alternativa normal es dirigir el nombre del script al iniciar mysql desde la línea de comando:
¡Espero que sea de utilidad para alguien!
Editar: Acabo de recordar otro: al invocar mysql desde la línea de comando, puede usar el modificador -t para que la salida esté en formato de tabla, una verdadera bendición con algunas consultas (aunque, por supuesto, terminar las consultas con \ G como se menciona en otra parte aquí también es útil a este respecto). Mucho más sobre varios conmutadores Herramienta de línea de comandos
Acabo de descubrir una forma sencilla de cambiar el orden de una clasificación (normalmente use Case ...) Si desea cambiar el orden de una clasificación (tal vez ordenar por 1, 4, 3, 2 en lugar de 1, 2, 3, 4) puede utilizar la función de campo dentro de la cláusula Order by. Por ejemplo
Ordenar por campo (sort_field, 1,4,3,2)
fuente
No creo que esto sea específico de MySQL, pero me ilumina:
En lugar de escribir
Puedes escribir
fuente
mysqlsla: una de las herramientas de análisis de registro de consultas lentas más utilizadas. Puede ver las 10 consultas de preocupaciones principales desde la última vez que lanzó registros de consultas lentas. También puede indicarle la cantidad de veces que se disparó una consulta MALA y cuánto tiempo total tardó en el servidor.
fuente
Realmente documentado , pero muy molesto: conversiones automáticas para fechas incorrectas y otras entradas incorrectas.
En cuanto a las fechas: a veces tendrás "suerte" cuando MySQL no ajusta la entrada a fechas válidas cercanas, sino que la almacena como,
0000-00-00
por definición, no válida. Sin embargo, incluso entonces, es posible que desee que MySQL falle en lugar de almacenar silenciosamente este valor.fuente
El Analizador de SQL integrado .
fuente
InnoDB por defecto almacena todas las tablas en un espacio de tabla global que nunca se encogerá .
Puedes usar
innodb_file_per_table
que colocará cada tabla en un espacio de tabla separado que se eliminará cuando suelte la tabla o la base de datos.Planifique esto con anticipación, ya que debe volcar y restaurar la base de datos para recuperar espacio de lo contrario.
Uso de espacios de tabla por tabla
fuente
Si inserta en la columna de fecha y hora el valor de cadena vacía "", MySQL retendrá el valor como 00/00/0000 00:00:00. A diferencia de Oracle, que ahorrará valor nulo.
fuente
Durante mis evaluaciones comparativas con grandes conjuntos de datos y campos DATETIME, siempre es más lento hacer esta consulta:
Que este enfoque:
fuente