2011-03-28 23 views
36

Tengo una columna en una tabla que solía ser varchar (255) al principio y debido a algunos cambios de diseño ahora es varchar (1536) = 1024 + 512. No buscaré ni indexaré este campo, ¿tiene sentido almacenar este valor en un tipo de datos diferente a varchar si desea optimizar esto para el rendimiento?Qué tipo de datos de columna debo usar para almacenar grandes cantidades de texto o html

+0

Esto debería resolver el problema - https://stackoverflow.com/questions/9322569/whats-the-best-way-to-store-html-code-in-mysql – venky

Respuesta

23

Sí, será mejor si puede almacenar los valores en el tipo de datos "TEXT". Para obtener más información, lea this article.

En cuanto al conocimiento de los requisitos de almacenamiento, puede leer this one.

Espero que ayude.

2

Yo usaría text para columnas con longitud variable.

8

Debe utilizar un archivo, no una base de datos para almacenar esto. Especialmente no MySQL. Hice una reseña una vez que explicaba qué sucede si, por ejemplo, descargas imágenes desde una base de datos BLOB, mira http://mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html. Usando archivos, puede usar la ruta rápida del servidor web usando la llamada al sistema sendfile (2), y es mucho más rápido usar esto.

MySQL tampoco tiene una API BLOB. Eso significa que es imposible cargar o descargar objetos de un tamaño superior a max_allowed_packet, y es difícil trabajar en ese sentido utilizando SUBSTRING(), ya que eso hará innecesarias copias de cadenas en la memoria del servidor.

Si usted DEBE almacenar datos BLOB o TEXT en el servidor, tiene la opción de TINYTEXT, TEXT, MEDIUMTEXT y LARGETEXT que están limitados a 255, 65535, 16 MB y 4GB de datos en el servidor, adicionalmente restringido por max_allowed_packet.

La información BLOB o TEXT grande arruinará por completo la densidad de datos en su tabla. Es útil crear una relación artificial 1: 1 o 1: 0 con una tabla BLOB, y luego almacenar los blobs en esta tabla adicional.

Cuando MySQL muestra un plan de consulta que es 'using tempoary', significa que el servidor necesita materializar la tabla de conjuntos de resultados en el servidor antes de entregar el resultado. Esto se está haciendo usando tablas de MEMORIA, si es posible. Cualquier tipo de TEXTO o BLOB no se puede representar en tablas de MEMORIA, por lo tanto, la tabla temporal luego golpea el disco como una tabla MyISAM.

Necesita buscar esos planes de consulta y convertirlos en algo que cargue los valores de ID de los valores BLOB/TEXT en su lugar. En una segunda consulta, entonces SELECCIONARía id, thetext FROM texttable WHERE id en (...) para obtener los valores TEXT/BLOB. Eso hará que la consulta con 'using temporary' no use los tipos TEXT o BLOB, y puede obtener los campos TEXT con una consulta trivial que se ejecuta sin 'usar temporal'.

Usted puede aprender más acerca de los detalles internos de MySQL TEXTO y almacenamiento BLOB mediante la lectura de http://www.mysqlperformanceblog.com/2010/02/09/blob-storage-in-innodb/

+0

"blob grande o T La información EXT destruirá por completo la densidad de datos en su tabla ". ¿Es esto cierto incluso si solo está utilizando la columna para almacenar 2kb de datos? –

+0

Depende del formato InnoDB (ver el enlace mysqlperformanceblog al final). Pero suponga que está poniendo 2KB TEXT más, digamos, 64 bytes de otros datos en una página InnoDB de 16 KB. Te deja con 5-6 filas/bloque, en lugar de cientos de lo contrario. Muy lento si busca datos no blob. Esa es la razón por la que el almacenamiento de BLOB cambió en las versiones posteriores de InnoDB (Barracuda ROW_FORMAT = DYNAMIC), básicamente construyendo internamente una tabla externa de este tipo. – Isotopp

74

Debe utilizar TEXT al igual que los otros decían, pero hay algunos consejos importantes cada vez que utilice TEXT o BLOB: ellos desacoplar Forme su tabla base ya que realmente ralentizan el acceso a la tabla.Imagine la siguiente estructura:

CREATE TABLE article (
    id INT(10) UNSIGNED, 
    title VARCHAR(40), 
    author_id INT(10) UNSIGNED, 
    created DATETIME, 
    modified DATETIME 
); 

CREATE TABLE article_body (
    id INT(10) UNSIGNED, 
    body TEXT 
); 

Cada vez que la lista de artículos que se pueden utilizar los article de mesa (5 últimos artículos del autor 33):

SELECT id, title FROM article WHERE author_id=33 ORDER BY created DESC LIMIT 5 

Y cuando alguien realmente se abre el artículo puedes usar algo como :

SELECT a.title, ab.body 
FROM article AS a 
    LEFT JOIN article_body AS ab ON ab.id = a.id 
WHERE a.id=82 
+11

+1 TEXTO o BLOB: desacople de su tabla básica –

+3

Pero si coloca el cuerpo en la misma tabla que los otros datos y cuando accede solo al ID y al título con la primera consulta SELECT anterior, ¿eso realmente ralentiza la tabla? ? Quiero decir que no lee ningún texto del cuerpo al ejecutar la consulta. –

+3

@Oskwish Para tipos de campo comunes como 'INT',' VARCHAR', 'DATE', etc., el motor de almacenamiento reservará el espacio máximo. Por ejemplo, un VARCHAR (100) siempre tendrá 100 bytes (+ metainformación) en el registro. De esta forma, se puede calcular una ** longitud de registro ** constante y el n-ésimo registro siempre estará en el desplazamiento 'n * longitud de registro'. - Por otro lado, sería un desperdicio reservar 65536 bytes para cada campo 'TEXT', por lo que asigna espacio dinámicamente. En esta situación, el tamaño de un redord ya no es fijo y requiere más operaciones para tratar con ellos. – vbence

Cuestiones relacionadas