martes, 24 de enero de 2012

Mi nueva asignacion: BizTalk (I)

Bueno, hoy ha sido un día delicado, me acaban de asignar un nuevo proyecto por el cual debo aprender BizTalk.

Esta tecnología es muy poco utilizada en la empresa donde trabajo, donde hay miles de personas, pero solo hay una con conocimientos sobre BizTalk.

Esto me ofrece una oportunidad de poder buscar una especialización dentro de la empresa.

Toda la información que vaya recopilando de Webs, Blogs, libros e incluso cursos online e-Lerning de Microsoft.

Thanks!!


lunes, 23 de enero de 2012

DateTime.UtcNow VS DateTime.Now


todas las operaciones internas en las que intervenga una hora deberían hacerse con horas en Tiempo Universal Coordinado, más conocido como UTC. Aunque a algunos pueda parecerles un capricho o un formalismo innecesario, son varias las situaciones en que agradeceremos usar UTC, y no solamente por su invariabilidad, sino también por su eficiencia.

Menos operaciones, menos incertidumbre

Antes de ver los casos caóticos, conviene saber qué tiene de provechoso usar UTC en el día a día. Por ejemplo, en el típico caso en el que queremos medir un lapso de tiempo ocurrido entre dos eventos (normalmente el principio y el final de una operación cuya eficiencia nos interesa especialmente).
DateTime comienzo = DateTime.Now;
// Operaciones cuya duración queremos medir
DateTime fin = DateTime.Now;
TimeSpan duracion = fin - comienzo;
Nuestro objetivo debe ser introducir el menor ruido posible en la medición, por lo que toda operación que no sea parte del conjunto a medir, debería ser lo más rápida posible. Dependiendo de la precisión deseada, puede ser fundamental conocer el funcionamiento interno de DateTime.Now: en primer lugar llama a DateTime.UtcNow, a continuación calcula el desfase horario en función de la zona establecida, y por último verifica si hay que aplicar la corrección por horario de verano. En resumen, DateTime.UtcNow es un par de órdenes de magnitud más rápido que DateTime.Now.
De hecho, en C# es incluso más rápido que la clase Stopwatch, creada ex profeso para este tipo de mediciones de precisión, pero que obviamente aporta más herramientas destinadas a dicho fin. Podemos verlo en este gráfico, obtenido a partir de un benchmarking realizado por Keyvan Nayyeri:

Eficiencia comparada de DateTime.Now, Stopwatch y DateTime.UtcNow

Trabajar con usuarios de todo el mundo sin volverse loco

Si ganar algunos milisegundos no es tu finalidad, no te preocupes, hay más motivos para utilizar UTC. Uno bastante importante es que tu aplicación sea utilizada por usuarios de distintas zonas horarias. Y ni siquiera es necesario que sean de países distintos.
Imagina: tu base de datos tiene un registro del usuario A, que utilizó la aplicación en Las Palmas de Gran Canaria, con hora 09:10; mientras que hay otro registro del usuario B, que utilizó la aplicación en su PC de Córdoba, a las 10:05. Si no recuerdas si la hora guardada se tomó en los clientes o en el servidor, puedes dudar acerca de cuál de los dos es anterior.
Pero es más, puedes encontrarte con este mismo problema con usuarios de una misma zona horaria. Es tan simple como que tu servidor pase a alojarse en un hosting de otro país, y si lo tienes configurado conforme a su información regional, las horas guardadas en él pueden dejar de significar lo que tú crees que significan.

Fatalidad, ocurre lo que no debería ocurrir cuando no debería ocurrir

Pero cuando de verdad se ve lo necesario que es usar datos invariables es en las situaciones excepcionales, aquellas en las que nunca solemos pensar, entre las que cabe destacar los cambios de hora debidos al ahorro energético.
Cambio horario de verano
Y es que el destino caprichoso puede querer que uno de tus usuarios comience una operación a las 2:59 CET del último sábado de marzo… ¡y la termine a las 2:00 CEST de ese mismo día por culpa del cambio al horario de verano! Es poco probable, pero puede ocurrir y fastidiarte contadores con tiempos negativos (o enormes por culpa de un desbordamiento). O que te pase como en Samoa, donde el gobierno decidió suprimir el 30 de diciembre de 2011 para mejorar sus relaciones económicas internacionales.
En definitiva, más vale pensar que lo peor puede pasar, y que no nos pille desprevenidos.

domingo, 22 de enero de 2012

Efecto mostrar/desvanecer barra de navegación de blogger

El siguiente codigo debe ser pegado al final de la cabecera </HEAD>

<script src='http://www.google.com/jsapi'/><script>
google.load(&quot;prototype&quot;, &quot;1.6.0.2&quot;);
google.load(&quot;scriptaculous&quot;, &quot;1.8.1&quot;);
</script>
<script type='text/javascript'>
function navbarShow() {
new Effect.Opacity(&#39;navbar-iframe&#39;, {duration:0.5, from:0.0, to:1.0});
}
function navbarHide() {
new Effect.Opacity(&#39;navbar-iframe&#39;, {duration:0.5, from:1.0, to:0.0});
}
function navbarHack() {
Event.observe(&#39;navbar-iframe&#39;, &#39;mouseover&#39;, navbarShow, false); Event.observe(&#39;navbar-iframe&#39;, &#39;mouseout&#39;, navbarHide, false); navbarHide();
}
Event.observe(window, &#39;load&#39;, navbarHack, false);
</script>

Hay que comprobar si ya estamos importando las librerías de java prototype.js o scriptaculous.js.Si ya los tenemos debemos quitar el primer <script>..</script>

<script src='http://www.google.com/jsapi'/><script>
google.load(&quot;prototype&quot;, &quot;1.6.0.2&quot;);
google.load(&quot;scriptaculous&quot;, &quot;1.8.1&quot;);
</script>

Al incrustar este código al final del apartado <HEAD>, hace que durante unos segundos y hasta que procesa todo el código, la barra de navegación de blogger se vea activa, mostrando al usuario que existe tal opción que después desaparecerá,

 y subiendo el puntero hacia su posición, se hará visible.

jueves, 19 de enero de 2012

Monitorizacion y optimizacion de SQL Server Querys (II)

Para continuar con el post anterior, pero con un método distinto de optimización de Querys voy a comentaros como trabajar con los Tools que nos proporciona SQL Server desde la version 2005.

Utilizaremos el Sql Server Profiler. Dicha herramienta nos permitirá crear trazas de todo nuestro trabajo sobre el motor de la base de datos.

Sql Server también nos proporciona DataBase Engine Turing Advisor que nos definirá, entro otros, que indices podemos necesitar en nuestras consultas, basándose sobre el optimización de consultas de SQL Server.



El primer paso es arrancar el programa Sql Server Profiler, donde lo asociaremos a nuestra base de datos y definiremos los eventos que el Profiler deberá monitorizar, normalmente dejo los eventos del profiler predeterminados. Además es importante que guardemos la traza en un documento, aunque también da la opción de almacenar la traza en una tabla.

Una vez terminadas las consultas y el trabajo sobre nuestros datos, pararemos la traza y saldremos del Sql Server Profiler.

A continuación arrancaremos el programa DataBase Engine Turing Advisor, creamos una nueva sesión asociándola a nuestra base de datos y pulsamos sobre  la opción de cargar desde documento, seleccionando el mismo archivo que creamos desde el SqlServer Profiler.

Terminada la prueba, se nos mostrara una lista de elementos (índices, statics) que nos recomiendan crear para mejorar nuestra arquitectura de la base de datos.

En los próximos días iré puliendo el texto e incorporando imágenes de los procesos.

Thanks!!

Monitorizacion y optimizacion de SQL Server Querys (I)

El objetivo que me plantearon es optimizar una base de datos para un programa, que utilizaba en la capa de conexión con los datos la tecnología de Linq -> LinqToSql.
Esta es una tecnología impresionante, pero hace de la optimización del servicio algo complicada, porque casi todo el trabajo se esta haciendo a nivel de codigo, no se utilizan Store Procedure o funciones.
Así pues, durante un tiempo me dedique a monitorizar mediante querys las consultas, observando parámetros que el propio servicio mide durante la gestión de las consultas.
Este es un ejemplo de dichas consultas:
-- Caution!! Fechas en formato AMERICANO
Declare @fechaInicioBusqueda as SmallDatetime;
                set @fechaInicioBusqueda = '1/1/2012';
Declare @fechaFinBusqueda as SmallDatetime;
                set @fechaFinBusqueda  = '1/29/2012';

select * from (
select SUBSTRING(st.TEXT, (qs.statement_start_offset/2)+1 , ((CASE qs.statement_end_offset WHEN -1 THEN datalength(st.TEXT) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS txt,
                creation_time,
                total_worker_time/execution_count AS AvgCPU,
                total_elapsed_time/execution_count AS AvgDuration,
                total_worker_time,execution_count,total_logical_reads,total_physical_reads,
                max_elapsed_time,min_elapsed_time,last_elapsed_time
                from sys.dm_exec_query_stats qs
                               cross apply sys.dm_exec_sql_text(sql_handle) st) as [tablaP]
                where (txt like 'select%')
                               and (creation_time > @fechaInicioBusqueda)
                               and (creation_time < @fechaFinBusqueda)
                ORDER BY AvgCPU DESC

También analice parte de la arquitectura de la base de datos, sin entran en detalla sobre cada table y sus definiciones, sino partiendo de comprobaciones como buscar tablas que no tengan indices o claves primarias(PK)

SELECT SCHEMA_NAME(o.schema_id) AS [schema]
,object_name(i.object_id ) AS [table]
,p.rows
,user_seeks
,user_scans
,user_lookups
,user_updates
,last_user_seek
,last_user_scan
,last_user_lookup
FROM sys.indexes i
INNER JOIN sys.objects o ON i.object_id = o.object_id
INNER JOIN sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
LEFT OUTER JOIN sys.dm_db_index_usage_stats ius ON i.object_id = ius.object_id AND i.index_id = ius.index_id
WHERE i.type_desc = 'HEAP'
ORDER BY rows desc


También hay comprobaciones en el lado de los indices como:

  1. Estudio de índices no declarados pero necesarios
  2. Encontrar índices sin uso
  3. Buscar consultas en la caché que les falta un Índice
  4. ...
Continuara ...

martes, 17 de enero de 2012

TIPS PARA OPTIMIZAR STORED PROCEDURE


  • Incluir la declaración SET NOCOUNT ON : Con cada instrucción SELECT y DML, el servidor SQL devuelve un mensaje que indica el número de filas afectadas por esa declaración. Esta información es útil sobre todo en la depuración del código, pero es inútil después de eso. Al establecer SET NOCOUNT ON, podemos desactivar la función de devolución de esta información adicional. Para los procedimientos almacenados que contengan varias declaraciones o contener bucles de Transact-SQL, el establecimiento de SET NOCOUNT en ON puede proporcionar un aumento de rendimiento importante porque el tráfico de red se reduce considerablemente.

CREATE PROC dbo.ProcNameAS
SET NOCOUNT ON;
--Procedure code here
SELECT column1 FROM dbo.TblTable1
-- Reset SET NOCOUNT to OFF
SET NOCOUNT OFF;
GO

  • Use el nombre de esquema con el nombre del objeto: El nombre del objeto está calificado si se utiliza con el nombre de esquema. El nombre de esquema se debe utilizar con el nombre del procedimiento almacenado y con todos los objetos de referencia dentro del procedimiento almacenado. Esta ayuda directamente a encontrar el plan compilado en lugar de buscar los objetos de otros esquemas posibles antes de decidirse a utilizar un plan en caché, si está disponible. Este proceso de búsqueda y decidir un esquema de un objeto lleva a un bloqueo de compilación en el procedimiento almacenado y disminuye el rendimiento del procedimiento almacenado. Por lo tanto, siempre se refieren los objetos con nombre completo en el procedimiento almacenado:
 SELECT * FROM dbo.MyTable -- Preferred method
-- Instead of
SELECT * FROM MyTable -- Avoid this method
--And finally call the stored procedure with qualified name like:
EXEC dbo.MyProc -- Preferred method
--Instead of
EXEC MyProc -- Avoid this method
  • No utilice el prefijo "sp_" en el nombre del procedimiento almacenado: Si un nombre de procedimiento almacenado comienza con "sp_", a continuación, SQL Server busca primero en la base de datos master y luego en la base de datos actual en donde están las sesiones con las que estamos trabajando. Buscar en la base de datos master causas sobrecarga adicional e incluso un mal resultado si otro procedimiento almacenado con el mismo nombre se encuentra en la base de datos master.
  • Use IF EXISTS (SELECT 1) en lugar de (SELECT *): Para comprobar la existencia de un registro de otra tabla, se utiliza la cláusula IF EXISTS. El SI devuelve cláusula EXISTS verdadera si el valor devuelto por una instrucción interna, ya sea un único valor "1 "o todas las columnas de un registro o registros completos. La salida de la declaración de la residencia no se utiliza. Por lo tanto, para reducir al mínimo los datos para el procesamiento y la transferencia de la red, debemos utilizar "1" en la cláusula SELECT de una instrucción interna, como se muestra a continuación:
    IF EXISTS (SELECT 1 FROM sysobjects
            WHERE name = 'MyTable' AND type = 'U')
  • Utilice el procedimiento almacenado sp_executesql en lugar de la instrucción EXECUTE.El procedimiento almacenado sp_executesql admite parámetros. Así, mediante el procedimiento almacenado sp_executesql en lugar de la instrucción EXECUTE mejorar la aptitud para la reutilización del código. El plan de ejecución de una sentencia dinámica se pueden reutilizar sólo si todas y todos los personajes, incluido el caso, el espacio, los comentarios y los parámetros, es el mismo para dos estados. Por ejemplo, si ejecutamos el siguiente lote:DECLARE @Query VARCHAR(100)DECLARE @Age INTSET @Age = 25SET @Query = 'SELECT * FROM dbo.tblPerson WHERE Age = ' + CONVERT(VARCHAR(3),@Age)EXEC (@Query) Si volvemos a ejecutar el lote anterior con valor diferente Edad @, entonces el plan de ejecución de sentencia SELECT creado para @ Edad = 25 no se pueden reutilizar. Sin embargo, si escribimos el lote de arriba se indican a continuación:DECLARE @Query NVARCHAR(100)SET @Query = N'SELECT * FROM dbo.tblPerson WHERE Age = @Age'EXECUTE sp_executesql @Query, N'@Age int', @Age = 25el plan compilado de esta instrucción SELECT se reutilizarán para el valor de diferentes parámetros de edad @. La reutilización del plan existente cumplimiento dará lugar a un mejor desempeño
  • Trate de evitar el uso de cursores de SQL Server siempre que sea posible: El cursor utiliza una gran cantidad de recursos para gastos de proceso para mantener la posición del registro actual en un conjunto de registros y esto reduce el rendimiento. Si necesitamos a los registros de proceso de uno por uno en un bucle, entonces debemos utilizar la cláusula WHILE. Siempre que sea posible, se debe sustituir el enfoque basado en el cursor con el enfoque basado en conjuntos. Debido a que el motor de SQL Server está diseñado y optimizado para realizar la operación SET-base muy rápido. Una vez más, por favor, tenga en cuenta el cursor es también una especie de bucle while.
  • Mantenga la transacción lo más pequeño posible: La longitud de la transacción afecta el bloqueo y los interbloqueos. El bloqueo exclusivo no se libera hasta el final de la transacción. En el nivel de aislamiento más alto, los bloqueos compartidos también son mayores con la transacción. Por lo tanto, las transacciones largas medios bloqueos por más tiempo y bloqueos durante más tiempo se convierte en el bloqueo. En algunos casos, el bloqueo también se convierte en callejones sin salida. Así, para una ejecución más rápida y menos de bloqueo, la transacción debe ser lo más corto posible.
  • Utilice try-catch para el control de errores: Antes de la versión de SQL 2005 para el control de errores, se usaba mucho código, porque una declaración de verificación de error fue escrito después de cada instrucción T-SQL. Más código siempre consume más recursos y tiempo. En SQL Server 2005, una manera simple introducción de la nueva con el mismo fin. La sintaxis es la siguiente: BEGIN TRY--Your t-sql code goes hereEND TRYBEGIN CATCH--Your error handling code goes hereEND CATCH

    .Ayuda: 
    Optimizar Store Procedure

Mejorar el rendimiento de aplicaciones ASP.NET


  1. Deshabilitar el estado de sesión: Si no se usa, entonces es mejor desactivarlo puesto que aparte de consumir recursos del servidor, generalmente también lo hace en el tráfico HTTP entre servidor y cliente al propagar el ID de la sesión. Esta opción se puede desactivar a nivel de la aplicación (elemento sessionState del web.config) o para páginas individuales (propiedad EnableSessionState).
  2. Activa el buffer de la página: Para reducir la comunicación entre cliente y servidor es mejor enviar los contenidos en bloque.
    When you run your ASP.NET application by using the ASP.NET process model, it is even more important to have buffering enabled. The ASP.NET worker process first sends responses to IIS in the form of response buffers. After the ISAPI filter is running, IIS receives the response buffers. These response buffers are 31 KB in size., After IIS receives the response buffers, it then sends that actual response back to the client. With buffering disabled, instead of using the entire 31-KB buffer, ASP.NET can only send a few characters to the buffer. This causes extra CPU processing in both ASP.NET as well as in IIS. This may also cause memory consumption in the IIS process to increase dramatically.
  3. Evitar la validación en el lado del servidor: En el artículo original el autor recomienda realizar la validación sólo en el cliente (javascript), pero en mi opinión, esto es un error, puesto que depender solamente de javascript para este tipo de cosas es como no hacer nada.
  4. Usar el control Repeater y evitar en lo posible el uso de los controles DataList, DataGrid y DataView: Los últimos no son recomendados porque generan mucho código HTML, pero en ASP.NET 2 esto se puede solventar usando los Control Adapters o usando otra forma para desarrollar aplicaciones ASP.NET.
  5. Usar HttpResponse.IsClientConnected: Verficar si el cliente todavía sigue conectado antes de realizar operaciones costosas.
    Consider using the HttpResponse.IsClientConnected property to verify if the client is still connected before processing a request and performing expensive server-side operations. However, this call may need to go out of process on IIS 5.0 and can be very expensive. If you use it, measure whether it actually benefits your scenario.
  6. Usar HTTPServerUtility.Transfer en lugar de Response.Redirect: El último envía las cabeceras necesarias (Location) al cliente y éste hace una nueva petición al servidor Web en base a esa cabecera.
  7. Usar siempre Page.IsValid cuando se trabaja con los controles de validación: Esto principalmente se debe a lo que comentaba en el punto 3, la única forma de asegurar que los datos cumplen con las reglas de validación definidas en esos controles -- de validación --, es verificando el valor de esa propiedad.
  8. Desplegar las aplicaciones en modo Release: Esto es para que se hagan las optimizaciones necesarias al momento de compilar la página y/o aplicación, además de otros Leer el siguiente importantes aspectos.
  9. Deshabilitar el seguimiento de página: No hay ninguna razón válida para que esta característica esté habilitada en una aplicación en producción.
  10. Page.IsPostBack es tu amigo: Hay acciones/código que puede evitarse cuando el cliente realiza una petición (envía la página a través del método POST).
  11. Minimizar el número de excepciones: En una aplicación y escenario ideal no habrá este tipo de problemas, pero como nosotros siempre nos equivocamos por el mismo hecho de ser humanos, tenemos que tomar medidas necesarias para reducir al mínimo posible el número de excepciones que genera una aplicación. Una lectura recomendada al respecto.
  12. Usar la cache: Poner en cache aquellos datos que no cambian mucho. Por otro lado, usar el cache de salida para páginas o partes de páginas que no cambian frecuentemente.
  13. Usar/crear cache por petición: Usar HttpContext.Items para mantener los datos que se necesitan en las diferentes etapas del proceso que sigue una página ASP.NET antes de llegar al cliente.
  14. Usar StringBuilder para operaciones intensivas con cadenas.
  15. Deshabilitar el ViewState: Toda la "magia" de los controles de servidor de ASP.NET dependen de esta característica: los datos se serializan en campos ocultos que se envían/reciben en cada petición. Así que si alguien quiere "venderles" ASP.NET con la idea de que hacer aplicaciones de escritorio es igual que hacer aplicaciones Web, ya saben cuáles son los inconvenientes.
  16. Usar paginación: Sólo recuperar los datos necesarios para la página que se visualiza, de preferencia esto se debe realizar desde la base de datos.
  17. Usar App_offline.htm para actualizar las aplicaciones.
  18. Usar ControlState en lugar del ViewState para los controles: En el artículo original se recomienda el uso del control de estado, pero hasta donde sé, da lo mismo usar uno u otro, porque el control de estado también tiene los mismos inconvenientes que el ViewState con la única diferencia que éste no puede deshabilitarse.
  19. Usar el bloque finally para asegurarse que todos los recursos son liberados adecuadamente, aunque también se puede usar la instrucciónusing para este caso.
  20. Usar Option Strict y Option Explicit, supongo que alguno que desarrolle en VB.NET puede justificar esta parte.
Buenos dias.

Hace tiempo que había desconectado del blog, seamos sinceros, solo dos personas lo ven.

Pero me gusta tener un sitio donde almacenar las cosas curiosas en las que voy trabajando.

En mi nueva empresa estoy desarrollando sobre tecnologías como Spring, NHibernate o LinqToSql, basándose en la comunicación y gestión de la base de datos.

Es por ello que buscando como optimizar la base de datos encontré esta entrada:

Optimización del rendimiento de las consultas de SQL Server

También es interesante la entrada sobre lo optimización de nuestro servidor con los indices
Nuevas herramientas para diagnosticar el estado de los índices

En los proximos dias subire una entrada de como hacer pruebas de rendimiento sobre Visual Studio 2010.

Thanks!!
 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Online Project management