Alvaro's profileTololo.NetPhotosBlogLists Tools Help

Tololo.Net

Blog de Alvaro Olivares, donde encontraras ejemplos en C#, SQL, patrones de diseño, arquitectura de software, mejores prácticas y tips.
October 17

Checklist para Internet Explorer 8

Etiquetas de Technorati: ,

Internet Explorer 8 es la nueva versión del browser que introduce un conjunto de mejoras y modificaciones para cumplir con los estándares.  Esto simplifica el desarrollo web puesto que hace más fácil que la página se vea igual en todos los navegadores.

El costo de esta estandarización de la web lo sufrirán las páginas que ya fueron desarrolladas para las versiones anteriores de Internet Explorer, las cuales pueden dejar de funcionar si es que no tomamos medidas al respecto.  A continuación se muestran los pasos a seguir para validar las páginas actuales.

Checklist para Sitios Web Existentes
  1. Navegar hasta el sitio web utilizando Internet Explorer 8
  2. Si las páginas se ven diferentes a como se veían en Internet Explorer 7 o no funcionan de la misma forma, activar la vista de compatibilidad pulsando el botón  BotonIE8
  3. Si el problema se soluciona activando la vista de compatibilidad, entonces agregue el meta tag para emular IE7 a las páginas con problemas
  4. Si el problema no se soluciona, verifique que la detección de User Agent que se está utilizando en la página reconoce a Internet Explorer 8
  5. Si la página aun no funciona, utilizar las herramientas de desarrollo incorporadas con Internet Explorer 8
Meta Tag

Al agregar el siguiente Meta Tag como primer elemento del head del documento se logra que IE8 despliegue la página como lo haría en la versión 7.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7“ />

Los valores posibles de este tag son: IE5, IE7, EmulateIE7, IE8 y Edge. Si eliges Edge la página siempre se desplegará como la versión más reciente del navegador.

 
TIPS
  1. Si es que la página se veía bien en Internet Explorer 7 y ahora se ve distinto, revisar todos los tag <p> están cerrados correctamente y que no hay <form> o <table> antes de cerrar el tag p
  2. El comportamiento de GetElementById en Internet Explorer 7 es distinto a lo que se especifica en el estándar, el por eso que IE8 modificó su comportamiento.  Antes la búsqueda se realizaba primero por id, luego por name y ambas búsquedas toleraban diferencias entre las mayúsculas y minúsculas.  IE8 solo busca por el Id y éste tiene que estar escrito en forma idéntica a como aparece en el documento.
October 15

Mejorando la experiencia de instalación del ambiente de desarrollo Web de Microsoft

Etiquetas de Technorati:

En un post anterior mencioné algunos de los muchos pasos requeridos para configurar el ambiente de de desarrollo de Microsoft, por suerte parece que Microsoft escuchó a los desarrolladores y han mejorado considerablemente este proceso.

Les presento el Microsoft Web Platform Installer, que aun esta en beta pero ya pueden comenzar a utilizar para facilitar el proceso de instalación.

Este instalador descarga las versiones gratuitas de todos los paquetes de instalación que se requieren para realizar un desarrollo web, incluyendo:

    • Internet Information Sertver 7
    • Visual Web Developer 2008 Express Edition
    • SQL Server 2008 Express Edition
    • .Net Framework 3.5 SP1

Los requisitos para el instalador son:

  • Windows Vista, Windows Server 2008
  • .Net 2.0 instalado

Lamentablemente el instalador no soporta a Windows XP.

Índices en SQL Server – Parte 4 – Non Clustered Index

Etiquetas de Technorati: ,

En los post anterior (parte 3) vimos como los clustered index controlan el orden físico de las filas en la tabla.  Ahora veremos como operan los índices Non-Clustered.

La siguiente ilustración muestra la estructura que tiene un non-clustered index.

grid.ai

Al igual que en el caso de los clustered index, los non-clustered index tienen un nodo raíz y muchos nodos en los niveles intermedios, estos a su vez pueden apuntar a nodos hojas o a otros nodos intermedios.  La diferencia se presenta en los nodos hoja, estos tienen almacenados solo el Id del registro y no todo el registro, por lo que se hacer necesario hacer una búsqueda sobre el índice cluster o sobre el heap para obtener el resto de las columnas de la fila.

La búsqueda parte desde el nodo raíz, este nodo tiene una lista de llaves, se comparan estas llaves para encontrar el nodo de nivel intermedio que contenga un rango de llaves que cubra la llave que se está buscando.  Luego se repite el proceso en los nodos intermedios hasta que se encuentre la llave que identifica a la fila correspondiente a la llave del índice.

Para ilustrar este proceso, realicemos una búsqueda de la llave AX04 sobre un non-clustered index.

Paso 1.- Contenido del Nodo Raíz (ID 0)

Llave Índice ID Nodo Intermedio
AA01 1
AG01 2
BA01 3
DB02 4
RF04 5
KJ01 6

Paso 2.- Contenido del Nodo Intermedio (ID 2)

Llave Índice ID Nodo Intermedio
AG01 10
AJ10 11
AP20 12
AZ30 13
BA20 14
BH50 15

Paso 3.- Contenido del Nodo Hoja (ID 12)

Llave Índice Llave
AP20 101
AQ10 50
AR12 160
AX04 123
AX24 145
AY25 12

Paso 4.- Hemos encontrado la fila (123), ahora debemos realizar una búsqueda utilizando índice cluster, conocido como bookmark lookup en SQL Server 2000/2005 y como key lookup en SQL Server 2008.

Llave ID Nodo Intermedio
1 1
100 2
160 3
300 4
500 5
1000 6

Paso 5.- Contenido del Nodo Intermedio (ID 2)

Llave ID Nodo Intermedio
100 10
110 11
120 12
130 13
140 14
150 15

Paso 6.- Contenido del Nodo Hoja (ID 12)

Llave Columna 1 Columna 2 Columna N
120 AX06 10000   XXX
121 AX02 10004   XXX
122 AX07 10000   XXX
123 AX04 20000 XXX
124 AX08 9000   XXX
125 AX01 1   XXX

En SQL Server la Llave Índice puede ser una o varias columnas, siempre y cuando el largo combinado de estas columnas no supere los 900 bytes.

Columnas Incluidas

SQL Server 2005 agregó una nueva funcionalidad a los índices non-clustered llamada “Columnas Incluidas” estas columnas no son parte de la llave índice, por lo que no se mantienen ordenadas dentro del índice y como consecuencia de esto solo es necesario almacenar su valor en el nodo hoja del índice.

En el ejemplo anterior, el paso 3 quedaría así al agregar la Columna 2 como una columna incluida del índice:

Llave Índice Llave Columna Incluida (Columna 2)
AP20 101 12000
AQ10 50 12332
AR12 160 12344
AX04 123 20000
124 145 12233
125 12 12221

Las columnas incluidas tienen varias ventajas:

  • Al utilizar columnas incluidas en el índice es posible superar la limitación de los 900 bytes para la llave del índice, manteniendo un índice eficiente.
  • Las modificaciones al valor de una columna incluida es más eficiente que la modificación de una columna que es parte de la llave del índice pues estas no requieren ser mantenidas en orden.
  • Es posible crear Covering Indexes, que son índices que incluyen todas las columnas requeridas para contestar una consulta específica, que no requieren la búsqueda sobre el clustered index.  Este tipo de índice es igual o más eficiente que u índice cluster.

Índices Filtrados

SQL Server 2008 agregó otra mejora a los índices non-clustered llamada “Índices Filtrados”.  Estos índices mantienen ordenados un sub conjunto de las filas de la tabla.

El uso más común de este tipo de índices se da cuando queremos crear un índice sobre una columna que permite valores nulos.  Al crear un índice normal podemos desperdiciar una gran parte del espacio de índice ordenando filas que tienen un valor nulo.

A continuación se describen algunos ejemplos de casos de uso para estos índices filtrados:

  • La columna “fecha de término de contrato” de la tabla empleado contiene una gran cantidad de filas con el valor nulo.
  • Los estados intermedios son buenos candidatos para ser índices filtrados. Es posible crear un índice que solo contenga las ordenes de compra recibidas y en proceso, pero no las despachadas.

 

Referencias:

October 13

Índices en SQL Server – Parte 3 – Clustered Index

Etiquetas de Technorati: ,

Como mencioné en los post anteriores (parte 1, parte 2) el clustered index controla el orden físico de las filas en la tabla, a diferencia de los índices Non-Clustered que funcionan como una lista ordenada de identificadores de fila.

La siguiente ilustración muestra la estructura que tiene un clustered index.

grid.ai

Todas las tablas que tienen un clustered index tienen un nodo raíz y muchos nodos en los niveles intermedios, estos a su vez pueden apuntar a nodos hojas o a otros nodos intermedios.  Esta estructura forma un árbol (B-Tree) que permite encontrar cualquier fila en forma eficiente.

La búsqueda parte desde el nodo raíz, este nodo tiene una lista de llaves, se comparan estas llaves para encontrar el nodo de nivel intermedio que contenga un rango de llaves que cubra la llave que se está buscando.  Luego se repite el proceso en los nodos intermedios hasta que se encuentre la página de datos que contenga el la fila específica.

Para ilustrar este proceso, realicemos una búsqueda sobre un clustered index de la llave 123.

Contenido del Nodo Raíz (ID 0)

Llave ID Nodo Intermedio
1 1
100 2
160 3
300 4
500 5
1000 6

Contenido del Nodo Intermedio (ID 2)

Llave ID Nodo Intermedio
100 10
110 11
120 12
130 13
140 14
150 15

Contenido del Nodo Hoja (ID 12)

Llave Columna 1 Columna 2 Columna N
120 AX06 10000   XXX
121 AX02 10004   XXX
122 AX07 10000   XXX
123 AX04 20000 XXX
124 AX08 9000   XXX
125 AX01 1   XXX

Para obtener el resultado se lee el nodo raíz, se busca el nodo intermedio que contiene a la llave 123, en este caso el nodo 2 contiene filas con llave entre 100 y 160.  Luego se repite el proceso, el nodo 12 contiene filas con llaves entre 120 y 130.  El nodo 12 es un página de datos por lo cual no necesitamos seguir buscando.

Cada vez que se agrega una fila a la tabla, SQL Server debe insertar la nueva fila en la posición correcta dentro del índice, esto puede ser una operación simple y eficiente si es que la página es la última del índice o si la página tiene espacio disponible (ver Fill Factor).  Si la página no tiene espacio es necesario dividir la página en 2, algo conocido como Page Split, que deja 2 páginas con un 50% de utilización.

Cada vez que se elimina una fila de la tabla, SQL Server eliminará la fila de la página, sin modificar ninguna otra página, lo cual limita el impacto de la operación a 1 sola página pero causa que se desperdicie mayor porcentaje de las página, proceso conocido como fragmentación.

Algo aun más costoso ocurre cuando se actualiza el valor de la llave del índice clustered, en este caso SQL Server debe copiar la fila desde la pagina original, aplicar los cambios indicados en el update, insertar la fila en la nueva página y finalmente eliminar la fila desde la página original.

October 07

Índices en SQL Server – Parte 2 - Tipos de índices

Etiquetas de Technorati: ,

Para mejorar el desempeño de las consultas se utilizan índices, los más utilizados son los Clustered y Non-Clustered.

Existen otros 3 tipos de índices que se utilizan para mejorar los tiempos de acceso a datos XML, a búsquedas de texto y de datos espaciales. A continuación se muestra la disponibilidad según la versión de SQL Server:

  Clustered Index Non-Clustered Index Full Text Index Xml Index Spatial Index
SQL Server 2000

si

si

-

-

-

SQL Server 2005

si

si (1)

si

si

-

SQL Server 2008

si

si (1 y 2)

si

si

si

(1) Permite definir Columnas Incluidas           (2) Permite definir Índices Filtrados

Los Clustered Indexes son índices que controlan el orden físico de las filas en la tabla, por lo cual solo puede existir uno para cada tabla.

Los Non-Clustered indexes son índices que mantienen un sub conjunto de las columnas de la tabla en orden.  Estos indices no modifican el orden de las filas de la tabla, en lugar de esto mantienen una lista ordenada de referencias a filas de la tabla original.

Para ilustrar la diferencia entre estos 2 tipos de índices podemos decir que las páginas blancas de la guía telefónica tienen un clustered index por Apellido(s) y Nombres, con lo cual puedo buscar de forma muy eficiente el número de teléfono de una persona si conozco sus apellidos y su nombre, una vez que lo encuentro obtendré su número de teléfono en forma inmediata pues el numero está al lado del nombre.

En el caso de las páginas amarillas de la guía telefónica la forma de buscar es un poco distinta, en este caso busco por rubro. Primero busco en un índice, el cual me indica en qué página se encuentra la lista de empresas que satisfacen la condición que busco. Esto mismo es lo que pasa cuando utilizo un índice Non-Clustered index una vez que encuentro lo que quiero en el índice debo ir a leer la fila específica para obtener el resto de los datos.

Veamos qué pasa cuando agregamos un índice a la columna Username de la tabla usuario que creamos en la parte 1.

UsernameIndex

El índice será Non-Clustered y Único puesto que no podemos tener más de un usuario con el mismo nombre.

Al volver a ejecutar la misma consulta, obtenemos lo siguiente:

IndexHeap

El plan de ejecución es un poco más complicado pero esta consulta es 100 veces menos costosa que la anterior. Ahora la consulta utiliza el índice para encontrar el RID, que es el identificador de la fila, con este RID hace una búsqueda en la tabla de tipo heap (RID Lookup).

Esta reducción de costo se explica por la cantidad de accesos a datos que esta consulta requiere, puesto que estos bajan desde 774 a solo 4 páginas lo que equivale 32 kb de datos contra 6192 kb, que eran necesarios antes de la creación del índice.

 

(1 row(s) affected)

Table 'Usuario'. Scan count 0, logical reads 4, physical reads 1, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Veamos otra alternativa, si utilizamos un clustered index en lugar de un non-cluster index no será necesario el lookup, por lo que el acceso será más eficiente.

ClusterIndexUsername

Ahora el plan de ejecución se ve así:

PlanClusterIndexUsername El acceso se ve así:

Table 'Usuario'. Scan count 0, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Como se puede ver el costo de esta consulta ahora es la mitad que con el índice non-clustered y en lugar de 4 lecturas lógicas tenemos sólo 2.

Es importante destacar que según Comparing Tables Organized with Clustered Indexes versus Heaps, es siempre recomendable utilizar tablas que utilicen un Cluster index en lugar de tablas que solo utilicen índices non-cluster.

En los próximos post veremos como diseñar los índices y llaves primarias de las tablas, de qué tipo deben ser y cuales son sus costos asociados.

 

Alvaro Olivares

Occupation
Location
Arquitecto de software que ha participado como instructor de los Workshops Académicos, en conferencias técnicas de MSDN y como consultor del Microsoft Innovation Center. Actualmente se desempeña como consultor en desarrollo de aplicaciones para Microsoft Chile

Spaces Maps

Loading...