Skip to content

Converting IMAGE to VARBINARY(max) on SQL Server

With Microsoft SQL Server 2005 the IMAGE and (N)TEXT large data types have been deprecated in favor of VARBINARY(MAX) and (N)VARCHAR(max). We have some older database schema at customers who still use the IMAGE type so I am preparing a note to guide the migration.

There is an easy ALTER TABLE command to convert the existing tables, however it is not clear what the impact of this conversion is. So I took a deeper look. I noticed that converting a VARBINARY(max) back to IMAGE caused a lot of I/O and log usage. The other way around this seems to not happen and I can not repeat the problem.

Nevertheless I tried a few scenarios with type and parameter conversion. With IMAGE the default is to not inline data and it is configured with the 'text in row' table option which allows to define a limit of data which is inlined.

The following statement creates 4 tables with different settings for images, two heap tables and two clustered:

DROP TABLE tableHeapWithImageDefault;
DROP TABLE tableHeapWithImageInline;
DROP TABLE tableClusteredWithImageDefault;
DROP TABLE tableClusteredWithImageInline;

CREATE TABLE tableHeapWithImageDefault (cID INT identity(1,1) PRIMARY KEY NOT NULL, cImage IMAGE);
CREATE TABLE tableClusteredWithImageDefault (cID INT identity(1,1) PRIMARY KEY CLUSTERED NOT NULL, cImage IMAGE);

CREATE TABLE tableHeapWithImageInline (cID INT identity(1,1) PRIMARY KEY NOT NULL, cImage IMAGE);
EXEC sp_tableoption 'tableHeapWithImageInline', 'text in row', 'ON';

CREATE TABLE tableClusteredWithImageInline (cID INT identity(1,1) PRIMARY KEY CLUSTERED NOT NULL, cImage IMAGE);
EXEC sp_tableoption 'tableClusteredWithImageInline', 'text in row', 'ON';

If I query the details I see the following:

select name, type_desc, lob_data_space_id, text_in_row_limit, large_value_types_out_of_row from sys.tables where name like 'table%'

name                             type_desc     text_in_row_limit large_value_types_out_of_row
tableClusteredWithImageDefault   USER_TABLE    0                 0
tableClusteredWithImageInline    USER_TABLE    256               0
tableHeapWithImageDefault        USER_TABLE    0                 0
tableHeapWithImageInline         USER_TABLE    256               0

The large_value_type_out_of_row cannot be modified as long as the table does not contain a new large type.

So lets fill the tables with smaller and larger values (total blob size of (36000+180)*50000=1.6GB) for the cImage column and see what space usage the allocation units have:

while @x < 10 BEGIN
  set @x = @x + 1
  select @x
  BEGIN TRANSACTION
  declare @i int = 0;
  while @i < 5000 BEGIN
    INSERT INTO tableHeapWithImageDefault(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),5)) -- 180
    INSERT INTO tableHeapWithImageDefault(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),1000)) -- 36000
    INSERT INTO tableHeapWithImageInline(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),5))
    INSERT INTO tableHeapWithImageInline(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),1000))
    INSERT INTO tableClusteredWithImageDefault(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),5)) -- 180
    INSERT INTO tableClusteredWithImageDefault(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),1000)) -- 36000
    INSERT INTO tableClusteredWithImageInline(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),5))
    INSERT INTO tableClusteredWithImageInline(cImage) VALUES(replicate(cast(newID() as VARCHAR(max)),1000))
    SET @i = @i + 1
  END
  COMMIT TRANSACTION
END

The following query looks at the three possible types of allocation units (especially IN_ROW_DATA for data stored in the table and LOB_DATA for large external data. The third type, ROW_OVERFLOW_DATA, is not used in this example):

select o.name AS tablename, au.type_desc, CEILING(au.used_pages * 8 /1024.0) as usedMB,
       au.data_pages, au.used_pages, au.total_pages, p.partition_number, p.rows,
       au.used_pages * 8 * 1024 / p.rows as [bytes/row]
FROM sys.allocation_units AS au
  JOIN sys.partitions AS p ON au.container_id = p.hobt_id
  JOIN sys.objects AS o ON p.object_id = o.object_id
WHERE o.name like 'table%';

The result shows as expected where the data is stored (keep in mind the average length for the rows includes long and short rows).

tablename                       type_desc       usedMB    data_pages  used_pages   total_pages  rows  bytes/row
tableHeapWithImageDefault       IN_ROW_DATA          5    582         586          587          100000       48
tableHeapWithImageDefault       LOB_DATA          1778    0           227574       227611       100000    18642
tableHeapWithImageInline        IN_ROW_DATA         16    1961        1971         1971         100000      161
tableHeapWithImageInline        LOB_DATA          1758    0           225003       225035       100000    18432
tableClusteredWithImageDefault  IN_ROW_DATA          5    582         586          587          100000       48
tableClusteredWithImageDefault  LOB_DATA          1778    0           227574       227611       100000    18642
tableClusteredWithImageInline   IN_ROW_DATA         16    1961        1971         1971         100000      161
tableClusteredWithImageInline   LOB_DATA          1758    0           225003       225043       100000    18432

So now we can also record the data pages used for the allocation units so we can verify after conversion that the data has actually not been touched (idea):

select o.name, au.allocation_unit_id, au.type_desc, au.total_pages, au.first_iam_page, au.first_page, au.root_page
from sys.system_internals_allocation_units au
  JOIN sys.system_internals_partitions AS p ON au.container_id = p.partition_id
  JOIN sys.objects AS o ON p.object_id = o.object_id
WHERE o.name like 'table%';

With the following result:

name                           allocation_unit_id type_desc    total   first_iam_page first_page     root_page
tableHeapWithImageDefault      72057594197966848  IN_ROW_DATA  587     0x3DB302000100 0x3CB302000100 0x748707000100
tableHeapWithImageDefault      72057594198032384  LOB_DATA     227611  0x3BB302000100 0x38B302000100 0x38B302000100
tableHeapWithImageInline       72057594198097920  IN_ROW_DATA  1971    0xB91507000100 0x2E8B06000100 0x3FDA00000100
tableHeapWithImageInline       72057594198163456  LOB_DATA     225035  0x478707000100 0x418707000100 0x418707000100
tableClusteredWithImageDefault 72057594198228992  IN_ROW_DATA  587     0x4F8707000100 0x4E8707000100 0x768707000100
tableClusteredWithImageDefault 72057594198294528  LOB_DATA     227611  0x4D8707000100 0x4C8707000100 0x4C8707000100
tableClusteredWithImageInline  72057594198360064  IN_ROW_DATA  1971    0x558707000100 0x548707000100 0x4FDA00000100
tableClusteredWithImageInline  72057594198425600  LOB_DATA     225043  0x578707000100 0x568707000100 0x568707000100

So and now finally we can alter the columns:

SET STATISTICS TIME ON
ALTER TABLE tableHeapWithImageDefault ALTER COLUMN cImage VARBINARY(MAX);
ALTER TABLE tableHeapWithImageInline ALTER COLUMN cImage VARBINARY(MAX);
ALTER TABLE tableClusteredWithImageDefault ALTER COLUMN cImage VARBINARY(MAX);
ALTER TABLE tableClusteredWithImageInline ALTER COLUMN cImage VARBINARY(MAX);
SET STATISTICS TIME OFF

And this returns in elapsed time = 0ms with the following new data layout. What is visible at first is that it has generated empty ROW_OVERFLOW_DATA allocation units for all rows (this might indicate that the conversion could differ if the rows are (nearly) full, which is not the case for our narrow tables in the experiment).

name                           allocation_unit_id type_desc          total first_iam_page first_page     root_page
tableHeapWithImageDefault      72057594197966848  IN_ROW_DATA          587 0x3DB302000100 0x3CB302000100 0x748707000100
tableHeapWithImageDefault      72057594198032384  LOB_DATA          227611 0x3BB302000100 0x38B302000100 0x38B302000100
tableHeapWithImageDefault      72057594198491136  ROW_OVERFLOW_DATA      0 0x000000000000 0x000000000000 0x000000000000
tableHeapWithImageInline       72057594198097920  IN_ROW_DATA         1971 0xB91507000100 0x2E8B06000100 0x3FDA00000100
tableHeapWithImageInline       72057594198163456  LOB_DATA          225035 0x478707000100 0x418707000100 0x418707000100
tableHeapWithImageInline       72057594198556672  ROW_OVERFLOW_DATA      0 0x000000000000 0x000000000000 0x000000000000
tableClusteredWithImageDefault 72057594198228992  IN_ROW_DATA          587 0x4F8707000100 0x4E8707000100 0x768707000100
tableClusteredWithImageDefault 72057594198294528  LOB_DATA          227611 0x4D8707000100 0x4C8707000100 0x4C8707000100
tableClusteredWithImageDefault 72057594198622208  ROW_OVERFLOW_DATA      0 0x000000000000 0x000000000000 0x000000000000
tableClusteredWithImageInline  72057594198360064  IN_ROW_DATA         1971 0x558707000100 0x548707000100 0x4FDA00000100
tableClusteredWithImageInline  72057594198425600  LOB_DATA          225043 0x578707000100 0x568707000100 0x568707000100
tableClusteredWithImageInline  72057594198687744  ROW_OVERFLOW_DATA     0  0x000000000000 0x000000000000 0x000000000000

And on the second glance we notice that neither the AU unit ID nor the page addresses has changed for any of the IN_ROW_DATA or LOB_DATA. So this means the change from IMAGE to VARBINARY(max) is low impact for the tested cases.

When turning on the out_of_row setting for the table(Heap/Clustered)WithDefault tables (which had no inline data before) the situation does not change. The elapsed time = 0ms and the result is unchanged:

SET STATISTICS TIME ON
exec sp_tableoption 'tableHeapWithImageDefault', 'large value types out of row', '1';
exec sp_tableoption 'tableClusteredWithImageDefault', 'large value types out of row', '1';
SET STATISTICS TIME OFF

Results in this (removed overflows):

name                           allocation_unit_id type_desc   total_pages first_iam_page first_page     root_page
tableHeapWithImageDefault      72057594197966848  IN_ROW_DATA 587         0x3DB302000100 0x3CB302000100 0x748707000100
tableHeapWithImageDefault      72057594198032384  LOB_DATA    227611      0x3BB302000100 0x38B302000100 0x38B302000100
tableClusteredWithImageDefault 72057594198228992  IN_ROW_DATA 587         0x4F8707000100 0x4E8707000100 0x768707000100
tableClusteredWithImageDefault 72057594198294528  LOB_DATA    227611      0x4D8707000100 0x4C8707000100 0x4C8707000100

Running the same option (elasped 15ms) change on the previously inlined-enabled tables:

SET STATISTICS TIME ON
exec sp_tableoption 'tableClusteredWithImageInline', 'large value types out of row', '1';
exec sp_tableoption 'tableHeapWithImageInline', 'large value types out of row', '1';
SET STATISTICS TIME OFF

With the unchanged pages:

name                          allocation_unit_id type_desc   total_pages first_iam_page first_page     root_page
tableHeapWithImageInline      72057594198097920  IN_ROW_DATA 1971        0xB91507000100 0x2E8B06000100 0x3FDA00000100
tableHeapWithImageInline      72057594198163456  LOB_DATA    225035      0x478707000100 0x418707000100 0x418707000100
tableClusteredWithImageInline 72057594198360064  IN_ROW_DATA 1971        0x558707000100 0x548707000100 0x4FDA00000100
tableClusteredWithImageInline 72057594198425600  LOB_DATA    225043      0x578707000100 0x568707000100 0x568707000100

So even that change has no impact. According to MSDN the reason for this is that the LOBs are only changed when updated. So this is also quite safe.

The same should be true for the other way around, however I have seen cases, where it took much longer with lots of logfile usage. Maybe you have an idea how I can recreate this scenario?

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

Didix on :

Dennis Okumu diabetes obat. Diabetes onatright ontario. 1200 a la semana Plan de comida de dieta keto barato. La vecina cocinaba unas acelgas con cerdo. Archivar debidamente la documentación. Bienvenido a Semana. Horario de Lunes a Domingo de a hrs. La mortalidad de esta pandemia en este país triplica la que ha tenido China. Estas son las seis lecciones que 1200 a la semana la tragedia 1200 a la semana viven los italianos. Una de ellas la 1200 a la semana de cuidar a las personas 1200 a la semana. El presidente y su gobierno atraviesan días difíciles. La ñeñepolítica, la baja popularidad, el coronavirus, el precio del dólar, la caída del petróleo y las disputas políticas se unieron y tienen a prueba el liderazgo presidencial. Mientras que el Gobierno muestra logros, los líderes del paro tienen listo el cronograma de las nuevas marchas. Las PYMEs constituyen la mayoría de las empresas del mundo, pero solo generan una quinta parte de los ingresos bancarios. Wendy Ramos se movilizaba en un articulado del sistema de transporte, en plena hora pico, cuando un hombre le tocó sus partes intímas. Ninguno de los pasajeros la auxilió. Traté de vivir una semana con el salario mínimo mexicano Síntomas de diabetes enfermería Diabeteszentrum hegau-bodensee-klinikum radolfzell suiza. Signos de diabetes Gardiner. Dr. Hyman diabetes diet. ¿Puedo engordar con la dieta ceto? Supermercado keto filipinas. Al no ser una ¿Puedo engordar con la dieta ceto? equilibrada, al reemplazar los ¿Puedo engordar con la dieta ceto? cotidianos por preparados proteicos, realmente se puede considerar insostenible a lo largo del tiempo dado que favorece el efecto rebote y el aumento de cortisol, la hormona del estrés. Anónimo 19 de diciembre de Si desea perder peso, es conveniente que acuda a un endocrinólogo y que este mismo o un nutricionista le paute una dieta adecuada a su salud, edad, actividad y sobre todo porque las dietas no se deben recomendar ni se deben comenzar sin una estricta vigilancia médica. La dieta cetogénica es rica en ¿Puedo engordar con la dieta ceto? y baja en carbohidratos. La dureza de las ¿Puedo engordar con la dieta ceto? tiende a verse dulcificada con la promesa de un " día especial " o "día de trampa" cada cierto tiempo. Eso induce al cuerpo a entrar en el estado llamado de ' cetosis '". Esto, recuerdan los investigadores, se ha asociado en estudios anteriores con un incremento del riesgo cardiovascular. La muestra de su trabajo era objetivamente pequeña y los autores coinciden en que son necesarios mayores estudios, pero sus conclusiones son suficientes como para prevenir contra una parada en seco si estamos siguiendo la 'dieta Keto'. Lo que sugiere nuestro estudio es que la 'dieta Keto' no es algo que puede hacer durante seis días y tomarte el domingo libre", concluye. 13 razones porque no estás bajando de peso con la dieta cetogénica ¿Las píldoras de dieta ceto del tanque de tiburones realmente funcionan. A decirle adiós no hay de otra. La central sindical ¿Puedo engordar con la dieta ceto? CGT informa de que las patronales del audiovisual bloquean el convenio estatal de técnicos a pesar de que han transcurrido La idea es lograr entrar en cetosis para alcanzar los objetivos de pérdida de peso. Hola por lo q veo todos sufrimos del mismo mal el maní. Pérdida de peso rápida de 30 horas Cantidad saludable de carne por día. El español en los medios. Puede que comas demasiada o muy poca proteína. Cuando tu describes algunos de ¿Puedo engordar con la dieta ceto? componentes de tu dieta que mencionas como saludable … A mi juicio ¿Puedo engordar con la dieta ceto? lo son. Sin una analítica completa y si desconocemos nuestro estado de salud general, nunca jugaremos con los milagros de una dieta cetogénica. El problema de la obesidad y el problema de la deficiencia de nutrientes son completamente diferentes. Hola a tod s, yo empecé el el 4 julio con 53, kilos y hoy 3 de agosto peso 49, kilos con keto. DIetas milagro, dietas que te hacen entrar en cetosis, perder peso en poco tiempo, siempre bajo el control médico. Hace unos meses te hablamos de la dieta keto. Cómo perder 25 libras en 2 semanas. En caso de detectarlo, procederemos a deshabilitar todas. Ésto consigue un efecto ahorrador ¿Puedo engordar con la dieta ceto? evitar en un exceso de gluconeogénesis. Y trató de tomar suficiente agua. Es conveniente probar otro tipo de dietas en donde exista una alimentación basada en el consumo de proteínas, hidratos de carbono reducidos y el aumento de las frutas y verduras. Existen todo tipo de dietas, y todas, sin dejar una, tienen efectos secundarios a largo plazo. Denervación renale diabetes medtronic Diabetes forschung heidelberg.

Likdix on :

Combattre diabetes naturellement bien. Diabetes hla merkmale. ¿Cuántos carbohidratos diariamente en la dieta ceto? Motivación para comer bien y perder peso. Es aconsejable esta dieta para adolecentes? Estoy en cetosis. Por otra parte, comer 5 veces al día no ayuda a activar tanto el metabolismo como hacer ejercicio. Buenos días. Qué pasa con los nopales? Quiero bajar de peso. No sólo eso, también logran mejoras en hipertensióncontrol de glucosa estudioestudiosíndrome metabólico estudiocolesterol HDL y triglicéridos estudio y ¿Cuántos carbohidratos diariamente en la dieta ceto? largo etcétera. Cuando sólo tienes un martillo, todo te parecen clavos. Como siempre, la evolución ofrece un buen marco conceptual de partida. A lo largo de nuestra historia, la latitud definía en gran medida nuestro acceso a carbohidrato. En regiones cercanas al ecuador, la recolección de plantas, frutas y raíces representaba una parte relevante de nuestra alimentación. Por supuesto encontramos también casos extremos. No hay reglas universales. LA DIETA CETOGÉNICA Atún para el diabetes Naranjas y diabetes spabel. Cura de diabetes faustman. Crema de diabetes goicoechea. Mejor dieta india para bajar de peso en un mes ¿Puedes comer leche con dieta ceto?. Esta nueva dieta se ha popularizado desde Japón y se dice que puedes perder varios kilos al mes. Natalia Prado. Miguel Bosé, que perdió 22 kilos con ella, habla maravillas de los beneficios que aportó a su salud física y mental. Esto se debe a que la alimentación es al mismo tiempo medicina y nos sirve para sentirnos sanos y fuertes. La consecuencia de ello es una gastronomía con gran personalidad. Y por no incluir carne de vaca, ya que es sagrada para la religión que profesan. En lugar de ello eligen una especie de mantequilla llamada ghee mejor dieta india para bajar de peso en un mes un yogur líquido conocido como lassi. Entre los ingredientes que no faltan en los platillos tenemos el arroz, el pollo y el cordero. Esto se debe a que la alimentación es al mismo tiempo medicina y nos sirve para sentirnos sanos y fuertes. Éstas estimulan el organismo, aumentan la temperatura corporal y ayudan a bajar de peso. De hecho, ésta es la razón por la que la comida de la India quema grasas. ¿Adelgazar para tener vida social? Así perdió 22 kilos esta joven india Mejores pastillas para bajar de peso 2019. Cómo adelgazar siguiendo esta dieta de comida india que contiene un secreto EC Desde el vaso de agua con limón que hay que tomar en ayunas hasta la ensalada que nos recomiendan para la mejor dieta india para bajar de peso en un mes, todo pasas por controlar el tamaño de las raciones. Y siempre que sea posible, hay que intentar añadir espinacas. Datos curiosos y sorprendentes de los pistaches. En el caso de aplicar con ese fin alguna información de este sitio, La Bioguía no asume la responsabilidad de esos actos. No admitimos publicaciones reiteradas de enlaces a sitios concretos de forma interesada. Spas para relajarse en pareja y salir de la rutina. Revisiones ajuste de anfeta Dieta vegetariana alta en proteínas para bajar de peso. Lactancia artificial. Datos curiosos y sorprendentes de los pistaches. Trucos para alimentar al niño. La nuez de la India Indian walnut es una semilla que se recomienda para bajar de peso en forma efectiva. Lo anterior puede llevar a un estado de deshidratación que nada tiene que ver con la eliminación de grasa, sino con la pérdida de electrolitos. Enseñó una nutrición adecuada. Aunque tiene siglos de tradición, ha tenido que ser un famoso cantante el que la popularizara. A menudo,…. Foto: El Mercurio. Gracia bumbry diabetes infantil Diabetes y alcohol slc2a2.

Add Comment

BBCode format allowed
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA