Microsoft Premier Support (PFE) Latin America

Este Blog está dedicado a todo aquel interesado en tecnología Microsoft, y con deseos de aprender de la experiencia y vivencias de los PFES de Latinoamerica y del grupo de Incubation Support & Services (ISS)

September, 2011

  • Memory Concepts on Windows

    Understanding the Memory concepts on Windows is an important part to note performance problems and resolve them.

    Many times the term of Physical memory can be confused with the concept of Virtual memory:

    Virtual Memory and Physical Memory

    The physical memory (RAM) is managed directly by the Windows Memory Manager. Every process has its own memory space and private memory address which can only be accessed by this process. The exception is the shared memory, which can be accessed by many processes.

    The physical memory has 3 states: Free, Reserved and Committed. On Free state the memory is free and inaccessible, on a Reserved State the memory is reserved to an specific process, and on a committed state the reserved memory is been used by the process and is been backed up by physical memory. For the memory to be free again, the process needs to free its reserved memory.

    Another part of the Physical memory is the page file which is by default located on the system drive. This file (pagefile.sys), is used as RAM memory, so in case a process needs a memory space on RAM and there isn’t availability, the Windows Memory Manager will make some room by moving data that is not in used to the page file, when this data its needed again, a reverse process will take place putting the data from the page file on RAM.

    Now, the Virtual Memory is a technique that allows a process to have the impression that is using a contiguous memory space, so if there where fragmentation will be transparent to the process. We can define the used Virtual Memory as the RAM memory + Page File used (always on committed state),

    It’s also convenient to talk about Virtual Address Space, each process has a private virtual space of memory also call Virtual Address Space or VAS, this mechanism prevent the processes to steps into each other memory space, and it’s the VAS space that you can overlook when finding memory problems.

    VAS is used on a memory mapping mechanism where physical memory (RAM and page file) is map to VAS by the Operating System. This way you can restrict direct access to physical memory and isolate each process.

    VAS and technology used:

    • ON 32 bits, VAS is limited to 4Gb on 2 regions of 2GB each: User Mode and Kernel Mode.
    • On Windows on Windows (WoW), which implies as 64 bits Operating System and a 32 bits application, VAS is as big as 4Gb also, however because the kernel is 64 bits it use a different VAS space than the 32 bits applications, this is why  the User Mode is 4Gb on WoW.
    • On 64 bits, VAS is limited to 16 Tb (Terabytes), been 8Tb for Kernel Mode and 8Tb for User Mode (7Tb on IA64)

    VAS Components

    • The User mode is the VAS portion the applications process will use, while the Kernel Mode, is the VAS portion that the operating system use to run DLLs, system files and more.
    • The VAS Kernel Mode it’s divided on 4 parts: Paged Pool, Non-Paged Pool, PTEs and system cache for drivers, Operating system kernel, etc.

    The kernel mode is an important part when doing a performance analysis on a server; we will see this on future posts.

    Memory tweaks

    The memory tweaks for 32 bits architectures are: 3GB, PAE and AWE

    Usually the 3GB and PAE switch are mistaken, they are both added on the boot.ini (Windows 2003) or the bcdedit command (Windows 2008/R2), but have different behaviors.

    • /3GB is used to modify the VAS User Mode, to make it 3Gb big instead of 2Gb, this implies that the kernel mode will be 1Gb big, this it’s not necessary on WoW, because the User Mode will have the 4Gb for himself.
    • /PAE is used to allow the CPU to address more Physical Memory, and more memory addresses, this is done by allowing 36 bits (2^36=68.719.476.736(64Gb)) pointers instead of 32 bits(2^32=4.294.967.296 (4Gb))  pointers.
    • AWE is commonly used on SQL Server; this allows it to access more than 4Gb of RAM until 64Gb. This works using some specific APIs to address memory using a windowing mechanism. You will need to enable “Lock Pages in Memory” right for the SQL Server account.

    These switches are only useful on 32 bits architectures, these switches are not needed on 64 bits architecture.

     

    “The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft”

     

  • Conceptos de Memoria en Windows

    Comprender los conceptos de memoria implementados en Windows es una parte fundamental para evidenciar problemas de performance y actuar en consecuencia.

    Muchas veces se suele confundir Memoria Física con el concepto de Memoria Virtual.

    Memoria Física y Memoria Virtual

    La Memoria Física (RAM) es manejada directamente por el Administrador de Memoria de Windows (Windows Memory Manager). Cada proceso tiene su propio espacio de memoria y sus propias direcciones privadas en memoria, las cuales solo pueden ser accedidas por el mismo proceso, la excepción es la de la memoria compartida (Shared Memory), la cual puede ser accedida por uno o varios procesos.

    La Memoria Física se puede encontrar en 3 estados: Free, Reserved y Committed. En el estado Free la memoria está libre y no puede ser usada por los procesos, en estado Reserved la memoria se encuentra reservada para un proceso, y en estado Committed, la memoria que se reservada es usada por el proceso y por lo tanto es respaldada por memoria física. Para que la memoria vuelva a estar en estado libre, el proceso que la tiene reservada debe liberarla.

    Parte de la Memoria Física, es también el archivo de paginación (page file) el cual va a estar ubicado por defecto en la unidad de disco del sistema. Este archivo (pagefile.sys), se utiliza como si fuera memoria del tipo RAM, de tal manera que si un proceso necesita espacio en memoria y no lo tiene, el Administrador de Memoria consigue ese espacio pasando datos que no están siendo utilizados al page file, y cuando estos datos se requieran nuevamente, se hará el proceso inverso, del page file a memoria (RAM).

    Ahora bien, la Memoria Virtual es una técnica que permite a un proceso tener la impresión de que tiene un espacio de memoria que es contiguo, por lo tanto si existiese fragmentación, para el proceso es transparente. Podemos definir como Memoria Virtual utilizada, al conjunto de Memoria Física + Page file, dicha memoria siempre tiene un estado committed.

    Para comprender mejor la Memoria Virtual, es conveniente verla en términos de Espacio de Direcciones Virtuales (VAS). A cada proceso se le asigna un espacio privado virtual de memoria también llamado Espacio de Direcciones Virtuales (Virtual Address Space, VAS). Este mecanismo previene que los procesos accedan espacios de memoria de otros procesos. Y es justamente VAS, un recurso de memoria que generalmente se pasa por alto cuando hay problemas de memoria.

    VAS es un espacio lógico y virtual de memoria el cual es mapeado a la Memoria Física (no sólo RAM, sino también el page file) por el Sistema Operativo para hacer un mapa de direcciones de memoria. De esta manera se restringe el acceso directo a la Memoria Física, proporcionando un aislamiento a cada proceso.

    VAS dependiendo de la tecnología

    • En 32 bits, VAS se encuentra limitado a 4Gb dividido en 2 regiones de 2Gb cada una: Modo Usuario y Modo Kernel.
    • En WoW (Windows on Windows), que implica el Sistema Operativo en 64-bits y la aplicación que ejecuta un proceso en 32-bits, el VAS es de 4Gb también, pero como el kernel es de 64-bits, no ocupa el mismo VAS que en 32-bits, por lo que los 4Gb quedan completamente para el Modo Usuario.
    • En 64-bits, VAS está limitado a 16Tb (terabytes), siendo 8Tb para el Modo Kernel y 8Tb para el Modo Usuario (7Tb en IA64).

    Partes del VAS

    • El Modo Usuario es la porción de VAS que los procesos de las aplicaciones van a utilizar, mientras que el Modo Kernel, es la porción de VAS que el Sistema Operativo utiliza para correr DLLs, archivos de sistema y demás.
    • El VAS del Modo Kernel se divide en 4 partes: Paged Pool, Non-Paged Pool, PTEs y el espacio para el cache del sistema, drivers, kernel del Sistema Operativo, etc.

    El Modo Kernel es una parte muy importante al momento de hacer un análisis de la performance de un servidor. Esto lo veremos en otro post, dedicado al Modo Kernel.

    Modificadores de Memoria

    Los modificadores de memoria una arquitectura de 32 bits son: 3GB, PAE y AWE.

    Suele suceder que se confunda el uso de 3GB y PAE, si bien ambos se agregan en el archivo boot.ini (Windows 2003) o con el comando bcdedit (Windows 2008), se utilizan para diferentes propósitos:

    • 3GB se usa para modificar el tamaño del VAS del Modo Usuario, modificandolo a 3Gb en vez de 2Gb de tamaño, lo que implica que el VAS del modo kernel quedará con 1Gb de tamaño. En WoW no es necesario el uso de 3GB, ya que el Modo Usuario puede hacer uso de los 4Gb del VAS, puesto que el Modo Kernel en 64-bits usa un espacio de direcciones diferentes.
    • PAE se usa para permitirle al procesador el acceso a más Memoria Física, pudiendo direccionar una mayor cantidad de direcciones de memoria, haciendo que en vez de usar punteros de 32, use punteros de 36 bits. Lo cual permite superar el límite de 32 bits de 4Gb de Memoria Física (2^32=4.294.967.296 (4Gb)) y usar un límite de 36 bits el cual es de 64Gb de Memoria Física (2^36=68.719.476.736(64Gb)).
    • AWE se utiliza comúnmente en SQL para que este pueda acceder a más de 4Gb de Memoria Fisica, hasta 64Gb. La forma en que funciona AWE es a través de APIs al permitir asignar directamente páginas de memoria usando un mecanismo de ventanas a la memoria fisica. Para que este fincione correctamente se debe de habilitar el permiso de “Lock Pages in Memory” para la cuenta que corre el servicio de SQL.

    Los Anteriores switches son solo relevantes en arquitecturas de 32 bits, con el uso de tecnologías de 64-bits dichos switches no son necesarios.

     

    “Las opiniones e ideas expresadas en este blog son las de los Autores y no necesariamente declaran o reflejan la opinión de Microsoft”

    Este material tambien lo podras acceder en http://blogs.technet.com/b/sql_pfe_latam/

  • SharePoint does not change the time like Windows automatically?

    Hey there SharePoint guys,

    This post is intended to help to people that a Time Zone change applied before or after the standard and SharePoint operations are being registered with the incorrect time.

    SharePoint is not able to synchronize its "clock" automatically with Windows clock, therefore if standard or daylight saving time start before or after the previously established by countries around the world every transaction like workflows stuff, upload/download, modify, add or delete will be registered with a wrong time. The change to the correct time must be manually, but ¿how to do it? you simply need to edit a file called TimeZone.xml that lives in Drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Config.

    For detailed information please check: http://support.microsoft.com/kb/888253

    Anyway, it does not make sense to write a post if this is to provide a Microsoft document, today I will give you an example of how to edit the xml file using an example of a support case that came from Chile in LATAM.

    Scenario

    By default Daylight Saving time in Chile must change every second sunday of October, this time goverment decided to start before in August 20th (3rd Sunday of the month). This as I told you before affect every transaction in SharePoint and some support cases arrived to Microsoft support.

    Since we cannot change the time automatically using Central Admin we need to follow the next steps:

    - Using SharePoint server hosting the Central Administration site go to the path Drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Config

    - Locate fiel TimeZone.xml

    - MAKE A BACKUP OF THE FILE BEFORE EDITING IT

    - Use a text editor

    - Look for the ID 65

    - You will see tags like the following:

    <TimeZone ID="65" Name="(GMT-04:00) Santiago" Hidden="FALSE">
            <Bias>240</Bias>
            <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
            <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>10</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>
            <History Year="2008" Name="santiago2009">
                <Bias>240</Bias>
                <StandardTime>
                    <Bias>0</Bias>
                    <Date>
                        <Month>3</Month>
                        <Day>5</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <Second>59</Second>
                        <Milliseconds>999</Milliseconds>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </StandardTime>
                <DaylightTime>
                    <Bias>-60</Bias>
                    <Date>
                        <Month>10</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <Second>59</Second>
                        <Milliseconds>999</Milliseconds>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </DaylightTime>
            </History>
            <History Year="2007" Name="santiago2008">
                <Bias>240</Bias>
                <StandardTime>
                    <Bias>0</Bias>
                    <Date>
                        <Month>3</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </StandardTime>
                <DaylightTime>
                    <Bias>-60</Bias>
                    <Date>
                        <Month>10</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </DaylightTime>
            </History>
        </TimeZone>

    - Please pay attention to tags named STANDARDTIME and DAYLIGHTTIME

    <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
       <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>10</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>

    - What we will do is to modify TEMPORARILY  the tag DaylightTime

    - We have a variable named <Month> with a value of 10  which refers to October

    - Nex for the variable named <Day> which is related to the weekend number has a value of 2, second weekend of the month.

    - Change will be done for = August 20th 2011

    - According to the calendar this is the THIRD weekend of the month

    - Editing TIMEZONE.xml file will look like:

    <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
      <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>8</Month>
                    <Day>3</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>

    NOTE: If you have more than 1 server in the farm you must edit every file for each server, at the end of the editing xml file do an IISRESET. Once this change is concluded please restore the backed up file.

    Good Luck!!

  • La hora en SharePoint no corresponde con la hora de Windows?

    Saludos comunidad,

    Este post tiene la intención de ayudar a todos aquellos que en sus paises el cambio de horario ya sea horario de verano u horario normal ha tenido afectación en sus Sitios de SharePoint.

    SharePoint no tiene la capacidad de sincronizar el cambio de horario con el horario que maneja el Sistema Operativo, por lo tanto cuando el cambio de horario se adelanta o se atrasa ustedes verán una afectación directa en el registro de cada operación que realicen en SharePoint. Es mandatorio que ustedes ajusten este tiempo manualmente, ¿y cómo hacerlo? en realidad lo que debemos hacer es editar un archivo llamado TimeZone.xml que vive en Drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Config.

    Ustedes pueden encontrar la información detallada en el artículo siguiente: http://support.microsoft.com/kb/888253

    En fin, no tendría ningún caso escribir un blog si éste es para dar una referencia a un documento de soporte, un servidor les dará un ejemplo de como editar el archivo utilizando el caso más reciente de cambio de horario que se dió en la hermana República de Chile

    Escenario

    Por defecto el horario de Verano en Chile debio cambiar en Octubre el segundo domingo del mes, pero el gobierno decidió adelantarlo al día 20 de Agosto (3er Domingo del Mes). Este cambio afectó el registro de horas y el equipo de soporte de Microsoft ha recibido casos de soporte relacionados a esta condición.

    No hay forma de que automáticamente SharePoint actualice el cambio así que estos son los pasos:

    - En el servidor que ejecuta la Administración Central ir a la ruta Drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Config

    - Ubicar el archivo TimeZone.xml

    - HACER UN RESPALDO DEL ARCHIVO ANTES DE EDITARLO

    - Editar con Notepad

    - Buscar el ID 65

    - Las entradas se observan como sigue:

    <TimeZone ID="65" Name="(GMT-04:00) Santiago" Hidden="FALSE">
            <Bias>240</Bias>
            <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
            <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>10</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>
            <History Year="2008" Name="santiago2009">
                <Bias>240</Bias>
                <StandardTime>
                    <Bias>0</Bias>
                    <Date>
                        <Month>3</Month>
                        <Day>5</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <Second>59</Second>
                        <Milliseconds>999</Milliseconds>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </StandardTime>
                <DaylightTime>
                    <Bias>-60</Bias>
                    <Date>
                        <Month>10</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <Second>59</Second>
                        <Milliseconds>999</Milliseconds>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </DaylightTime>
            </History>
            <History Year="2007" Name="santiago2008">
                <Bias>240</Bias>
                <StandardTime>
                    <Bias>0</Bias>
                    <Date>
                        <Month>3</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </StandardTime>
                <DaylightTime>
                    <Bias>-60</Bias>
                    <Date>
                        <Month>10</Month>
                        <Day>2</Day>
                        <Hour>23</Hour>
                        <Minute>59</Minute>
                        <DayOfWeek>6</DayOfWeek>
                    </Date>
                </DaylightTime>
            </History>
        </TimeZone>

    - Observen que tenemos 2 Tags que identifican al tiempo estándar y al horario de verano

     <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
       <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>10</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>

    - Lo que haremos será modificar TEMPORALMENTE  el Horario de Verano DaylightTime

    - Como se puede observar en la variable <Month> tenemos 10  que corresponde al mes de Octubre

    - En la variable <Day> que corresponde al fin de semana donde el cambio de horario debería aplicar en este caso es 2, segundo fin de semana del mes.

    - El cambio que debemos realizar de acuerdo a la fecha en la que el gobierno decidió adelantar el horario de verano = 20 de Agosto 2011

    - De acuerdo al calendario debió ocurrir el TERCER fin de semana

    - El cambio  en TIMEZONE.xml debería ser:

     <StandardTime>
                <Bias>0</Bias>
                <Date>
                    <Month>3</Month>
                    <Day>2</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </StandardTime>
      <DaylightTime>
                <Bias>-60</Bias>
                <Date>
                    <Month>8</Month>
                    <Day>3</Day>
                    <Hour>23</Hour>
                    <Minute>59</Minute>
                    <Second>59</Second>
                    <Milliseconds>999</Milliseconds>
                    <DayOfWeek>6</DayOfWeek>
                </Date>
            </DaylightTime>

    NOTA: Si hay más de 1 servidor en la granja el cambio se debe hacer en cada servidor, es necesario realizar un IISRESET al terminar de editar cada archivo. Al terminar el horario de verano por favor regresen el archivo que respaldaron.

    Saludos y buena suerte

  • Linked Server behavior when used on JOIN clauses

    Recently, a client had some performance problems with a query that executed a join with a remote table using a linked server. The client asked why similar queries, that use filters over the local tables and returned a few rows, sometimes compile IO expensive queries on the remote server.

    It’s important to know how SQL Server compile queries with remote tables, this will help us to tune our queries and have good response times, because by using less IO and transferring less data over the network we will have a better performance.

    When working with linked servers is very important to know that SQL Server must send the data from the remote server to the servers that is calling the remote object to evaluate and apply the filters defined in the JOIN clause.

    When you use Linked Servers on a JOIN clause, SQL Server will compile the best plan to execute the query, avoiding unnecessary data transmission over the network, so the query will take less time to execute. Let’s review some examples step by step of how SQL Server manages queries involving remote tables:

    CASE 1: On the following example the JOIN uses a remote table and no filters are in-place. You can see that all records are returned from the remote server because when you don’t have filters all the records are necessary on the local server to evaluate and execute the JOIN condition.

     

    CASE 2: to the case 1 query we applied a filter on a column of the remote table. You can see that SQL Serve check the statistics of the remote table to build the best query, and you can see the filter statement for the remote table on the identified column

     

    CASE 3a: to the case 1 query we applied a filter on a column of the local table. You can see that SQL Server first apply the filter and if it obtains a low number of different values (relative per query) after applying the filter, it builds a query to get only the necessary data from the remote table using the JOIN condition on the corresponding field, and this will be execute as many times as different values return the filter on the local table.

    CASE 3b: to the case 1 query we applied a filter on a column of the local table. You can see that SQL Server first apply the filter and if it obtains a high number of different values (relative per query) after applying the filter, SQL Server will send one query with no filters, it only specifies the required columns and sorts the result on the JOIN condition field to help the execution, because it will need to execute a Merge Join instead of a Nested Loop Join.

    NOTE: you will see this behavior with either the existence of an index on JOIN field or not

    CASE 4a: to the case 1 query we applied a filter on a column of the local table that causes that no record is returned for the table and so no record is returned for the query. As you can see SQL Server will not execute a query to return data (because it’s not necessary), however it will establish a session to the remote server and execute some queries to return statistics and to get a schema lock on the remote table.

    The same will happen when you execute the same query form the case 1, but with a condition that makes that no record is returned when the filter its applied on the remote table: no query to return data is executed after checking the remote table statistics.

    CASE 4b: to the case 1 query we applied a filter on a column of the local table that causes that no record is returned for the table and so no record it’s returned for the query, also we included a filter on the remote table on a column that have a UNIQUE index defined, you can see that unlike the case 4a, SQL Server will execute a query on the remote server using a filter on the indicated remote column.

    NOTE: LEFT JOINS and RIGHT JOINS will behave exactly the same way as an EQUAL JOIN. The queries send to the remote server will be built depending on the data to be returned, indexes and statistics.

    In the case reported by my client, the difference between executions of similar queries was caused because SQL Server wasn’t able to create the best query to be executed on the remote server after adding one or two conditions to the query, and the situation was even worse because of outdated statistics on the local and remote databases.

    After reviewing the SQL Server behavior when using Linked Servers on JOIN clauses, we can conclude:

    • Maintaining statistics updated is not only important for SQL Server to compile the best execution plans for local operations, they are also important when using linked servers in order to define if it’s necessary to execute a query against the remote server, and if necessary it will use them to build the best query to return the least amount of data possible.
    • Even if SQL Server determine that it’s not necessary to execute a query against the remote server to satisfy the query, SQL Server will establish a connection, query statistics and apply schema locks on the remote object, and this could lead to some delays and blocking, for example, a previous schema lock on the object will lead to a block.
    • On the developing and troubleshooting faces, analyzing the query that SQL Server executes on the remote server it’s really useful to identify the root cause of what it seems to be a bad behavior. The cases 3a and 3b are examples of cases on which distribution, data volume and statistics could lead to a big difference on performance. Cases 4a and 4b are example of SQL Server could design the remote queries differently just due to the use of different conditions.

     

    “The opinions and views expressed in this blog are those of the author and do not necessarily state or reflect those of Microsoft”

  • Comportamiento de Linked Servers cuando se utilizan en Joins

    Recientemente trabajé en un caso donde un cliente presentaba problemas de desempeño con un query que realizaba un join con una tabla remota a través de un linked server. El cliente preguntó porque queries similares, que aplican condiciones sobre las tablas locales y retornaban pocos registros, generaban en algunas oportunidades consultas pesadas sobre el servidor remoto.

    Es importante conocer como SQL Server maneja las consultas con tablas remotas ya que esto nos permite entonar nuestros queries y tener buenos tiempos de respuesta, ya que al usar la menor cantidad de IO y transmitir la menor cantidad de datos a través de la red obtendremos un mejor rendimiento.

    Al trabajar con linked servers es muy importante estar consciente de que SQL Server debe enviar información desde el servidor remoto al servidor que hace la llamada para evaluar y aplicar la condición de JOIN.

    Al usar Linked Servers en la cláusula JOIN, SQL Server compilará el mejor plan para ejecutar la consulta, evitando transmitir información innecesaria a través de la red y de esa forma disminuir el tiempo requerido para satisfacer el query. Vamos a revisar paso a paso algunos escenarios para observar las diferentes acciones que SQL Server ejecuta en una instancia remota de acuerdo al tipo de query que se esté ejecutando:

    CASO 1: En el siguiente ejemplo se utiliza un JOIN con una tabla remota y sin filtros adicionales. Podemos observar en el servidor remoto que la sentencia ejecutada retorna todos los registros de la tabla, ya que al no existir ningún filtro todos los registros son necesarios para poder ejecutar el JOIN en el servidor local.

     Caso 2: Al query del caso 1 aplicamos un filtro sobre una columna de la tabla remota. Se observa que SQL Server consulta las estadísticas de la tabla remota para construir el query más adecuado, y efectivamente se observa que la sentencia enviada filtra la tabla remota por el campo indicado en el query.

     

    CASO 3a: Al query del caso 1 aplicamos un filtro sobre una columna de la tabla local. Se observa que SQL Server aplica primero el filtro local, y al obtener un número bajo (relativo para cada query) de valores diferentes para el filtro, construye un query  para obtener sólo la información necesaria de la tabla remota usando la condición sobre el campo correspondiente, y lo ejecuta tantas veces como valores diferentes retorne el filtro sobre la tabla local

    CASO 3b: Al query del caso 1 aplicamos un filtro sobre una columna de la tabla local, y se observa que SQL Server aplica primero el filtro local y al obtener un número alto (relativo para cada query) de valores diferentes para el filtro, SQL Server envía al  servidor remoto un único query que no tiene filtros definidos y sólo indica los campos requeridos aunque ordenado por el campo de condición del JOIN para facilitar la operación, ya que requiere ejecutar un Merge Join en vez de un Nested Loop como el ejemplo anterior.

    NOTA: esto se observa existiendo o no un índice por el campo del JOIN.

    CASE 4a: Al query del caso 1 aplicamos un filtro sobre una columna de la tabla local que causa que ningún registro sea retornado para la tabla y por lo tanto para todo el query. Se puede observar que SQL Server no ejecuta en el servidor remoto ningún query para recuperar valores de la tabla remota (ya que no los necesita), sin embargo, si establece sesión a la instancia remota y ejecuta una serie de operaciones para consultar estadísticas y bloquear el esquema de la tabla remota.

    Lo mismo sucede al ejecutar el mismo query del caso 1, pero con una condición que causa que ningún valor sea retornado al aplicarlo sobre la tabla remota: ninguna consulta es ejecutada contra el servidor remoto luego de que se validan las estadísticas de la tabla remota.

    Caso 4b: Al query del caso 1 aplicamos un filtro sobre una columna de la tabla local que causa que ningún registro sea retornado para la tabla y por lo tanto para todo el query, y adicionalmente incluimos un filtro para la tabla remota sobre un campo que tiene definido una índice UNIQUE, se puede observar que a diferencia del caso 4a, SQL Server ejecuta una consulta en la instancia remota filtrando la tabla por el campo indicado

    NOTA: Los LEFT JOINs y RIGTH JOINs se comportan exactamente de la misma manera que el EQUAL JOIN. Las sentencias enviadas al servidor remoto serán construidas dependiendo del volumen de datos, índices y estadísticas disponibles.

    En el caso puntual del cliente que tenía el problema, la diferencia en la ejecución estaba dada por que a pesar de ser queries similares al agregar una o dos condiciones adicionales, y empeorado por las estadísticas desactualizadas tanto en la base de datos local como en la base de datos remoto, SQL Server no era capaz de generar el mejor query para ser ejecutado en el servidor remoto.

    Luego de revisar el comportamiento de SQL Server al utilizar linked servers en clausulas JOIN, podemos concluir lo siguiente:

    • Mantener estadísticas actualizadas no sólo es importante para que SQL Server genere planes de ejecución óptimos en operaciones locales, sino que son de gran utilidad al utilizar linked servers para definir si es necesario ejecutar alguna consulta contra la instancia remota y de ser necesario construir el mejor query posible para retornar la menor cantidad de registros posible.
    • Aunque se determine que no es necesario ejecutar consultas contra el servidor remoto para satisfacer un query, SQL Server se conecta al servidor remoto, consulta estadísticas y aplica locks de esquema sobre el objeto remoto, por lo que puede existir aún retrasos para la ejecución del query por factores en la instancia remota, por ejemplo, un lock de esquema previo sobre el objeto utilizado generaría un bloqueo.
    • Durante las fases de desarrollo y troubleshooting, analizar las consultas que SQL Server ejecuta en el servidor remoto es de gran utilidad para identificar la causa de lo que parece ser un comportamiento errático de SQL Server. Los casos 3a y 3b son ejemplos de casos en los que la distribución, volúmenes de datos y estadísticas puede causar diferencias de performance significativas. Los casos 4a y 4b son ejemplos de cómo al utilizar ciertas condiciones en determinadas estructuras puede modificar la forma en que SQL Server diseña los queries remotos.

     

    “Las opiniones e ideas expresadas en este blog son las de los Autores y no necesariamente declaran o reflejan la opinión de Microsoft”

    Este material tambien lo podras acceder en http://blogs.technet.com/b/sql_pfe_latam/