{"id":202,"date":"2008-02-04T20:19:51","date_gmt":"2008-02-05T02:19:51","guid":{"rendered":"http:\/\/198.27.101.129\/blog\/itzcoaltam\/?p=202"},"modified":"2008-11-16T23:42:42","modified_gmt":"2008-11-17T05:42:42","slug":"optimizando-querys-en-sybase","status":"publish","type":"post","link":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/optimizando-querys-en-sybase\/","title":{"rendered":"Optimizando Querys en Sybase."},"content":{"rendered":"<p>Cuando te encuentras con la  presi\u00f3n de entregar un producto en un tiempo determinado y, seamos sinceros, han pasado cosas que no estaban en el plan, de tal forma que llevas ya con retraso considerable, escribes c\u00f3digo que no es optimo del todo, funciona, si, pero no esta optimizado y como pasa frecuentemente, cuando es probado ya con  un volumen de datos decente, y en ambientes mas cercanos a los que encontraras en producci\u00f3n, simplemente se demora eternidades.<\/p>\n<p>En ese momento, es cuando tienes que entrar a hacer lo que un programador con mucha mas experiencia realizar\u00eda desde el principio, escribir c\u00f3digo optimo.<\/p>\n<p>Pero, entremos en materia.<\/p>\n<p>Para poder realizar la optimizaci\u00f3n de querys, es necesario que entandamos un poco el como funciona el optimizador del engine de Sybase,  ello nos ayudar\u00e1 a comprender el por que en ocasiones las cosas no funcionan como deber\u00edan funcionar.<\/p>\n<p>Claro esta, deberemos conocer los elementos que intervienen  al momento de resolver una consulta, y los cuales pueden determinar si esta ser\u00e1 optima o no.<\/p>\n<p>De tal forma, empecemos analizando estos elementos.<\/p>\n<p><strong>\u00cdndices.<\/strong><\/p>\n<p>Los \u00edndices en sybase son fundamentales para la optimizaci\u00f3n de las consultas, se puede decir que todas las tablas requieren de por lo menos un \u00edndice, el cual deber\u00e1 estar conformado por los campos de la llave primaria, y el cual garantice la unicidad de los registros.<\/p>\n<p>Los \u00edndices pueden tener las siguientes caracter\u00edsticas.<\/p>\n<p><em>\u00danico.<\/em><\/p>\n<p>No permitir\u00e1 la inserci\u00f3n de mas de un registro con la misma informaci\u00f3n en cuanto a los campos que lo componen, es ideal para garantizar la unicidad, una tabla puede tener mas de un \u00edndice \u00fanico, por ejemplo la tabla  que almacene la informaci\ufffdn de contribuyentes puede tener un \ufffdndice \ufffdnico para el campo de RFC y otro \ufffdndice \ufffdnico para el campo de CURP.<\/p>\n<p><em>Clustered.<\/em><\/p>\n<p>Esta caracter\ufffdstica define el orden en el cual es guardada la informaci\ufffdn dentro de la tabla, ejemplo, en una tabla que no contenga un \ufffdndice clustered, cada vez que se inserta un registro, este es insertado en la ultima pagina de datos disponible, es decir, los registros no guardan un orden mas all\ufffd del de su inserci\ufffdn, sin embargo, si una tabla tiene un \ufffdndice clusterd, al momento de insertar un registro, este es puesto en el lugar que le corresponda de acuerdo al orden definido por los campos que integran el \ufffdndice clustered, esto es muy \ufffdtil para agilizar las consultas mas comunes, por definici\ufffdn, una tabla solo puede tener un \ufffdndice clusterd, y se conforma, por los campos que le den el orden a las consultas que las agrupen en un orden jer\ufffdrquico mas com\ufffdn, ejemplo: en una tabla que almacene las ventas diarias de productos por cliente, y que contenga los campos:<\/p>\n<blockquote>\n<blockquote><p>Fecha<br \/>\nCliente<br \/>\nProducto<br \/>\nVenta<br \/>\nPrecio<br \/>\nDescuento<br \/>\nImpuesto<\/p><\/blockquote>\n<\/blockquote>\n<p>El \ufffdndice clustered deber\ufffda estar compuesto por los campos Fecha, Cliente, Producto, no tendr\ufffda caso ordenar la informaci\ufffdn dentro de la tabla basado en los campos de Venta, Descuento, toda vez que esta no seria la organizaci\ufffdn jer\ufffdrquica mas com\ufffdn.<\/p>\n<p><strong>Query Plan<\/strong><\/p>\n<p>El optimizador de sybase realiza un plan de ejecuci\ufffdn de cada consulta que va a resolver, este plan de ejecuci\ufffdn es el que determina la forma en la cual realizara la b\ufffdsqueda de los datos, por ejemplo, puede determinar usar un \ufffdndice en lugar de otro (asumiendo que la tabla contiene mas de un \ufffdndice), si  creara una tabla temporal para realizar un ordenaci\ufffdn o una agrupaci\ufffdn<\/p>\n<p>En el caso de los procedimientos almacenados,  el momento que se crean dentro del engine de sybase, se determina el plan de ejecuci\ufffdn de todas las consultas que lo componen,  dicho plan de ejecuci\ufffdn es almacenado al igual que la definici\ufffdn del procedimiento, de tal forma, que al ser invocado,  solo se realiza el plan de ejecuci\ufffdn definido durante su creaci\ufffdn, esto puede presentar problemas de optimizaci\ufffdn posteriores, por ejemplo, tenemos una tabla de empleados la cual tiene solo un \ufffdndice por el campo RFC, creamos un procedimiento almacenado el cual solo contiene una consulta a esta tabla buscando a los registros cuya fecha de nacimiento sea igual a un valor determinado.<\/p>\n<p>Al momento de crear el procedimiento, el engine optara por hacer un barrido de todos los registros de la tabla, toda vez que no tiene ning\ufffdn \ufffdndice que pueda ayudar a filtrar la informaci\ufffdn solicitada, el plan de ejecuci\ufffdn es guardado junto con la definici\ufffdn del procedimiento, y cada vez que lo ejecute, utilizar\ufffd el mismo plan de ejecuci\ufffdn, que pasar\ufffda, si a la tabla del ejemplo  le creamos un \ufffdndice secundario que contenga solo el  campo fecha de nacimiento.<\/p>\n<p>El procedimiento almacenado ignorara el nuevo \ufffdndice, toda vez que no exist\ufffda durante su  creaci\ufffdn, por lo que no fue considerado por el optimizador de sybase al momento de crear el plan de ejecuci\ufffdn, para solucionar el problema, bastar\ufffd con regenerar el procedimiento almacenado.<\/p>\n<p>Debido a este punto, puede presentarse muchos problemas de optimizaci\ufffdn, es recomendable regenerar los procedimientos almacenados cuando existan cambios en la definici\ufffdn de los \ufffdndices, o cuando el volumen de datos contenidos en las tablas ha cambiado dr\ufffdsticamente.<\/p>\n<p><strong>Estad\ufffdsticas de Acceso.<\/strong><\/p>\n<p>Sybase lleva un registro estad\ufffdstico del n\ufffdmero de p\ufffdginas que debe leer para poder obtener un registro solicitado, estas estad\ufffdsticas est\ufffdn ligadas a cada uno de los \ufffdndices que contengan las tablas.<\/p>\n<p>El hecho  que el optimizador de sybase decida utilizar un \ufffdndice o no, puede ser provocado por la estad\ufffdstica de acceso al mismo, por ejemplo, en una tabla que normalmente contiene un volumen reducido de informaci\ufffdn, al ser alimentada por medio de un BCP con  volumen mucho mayor, los querys pueden optar por no utilizar el \ufffdndice que ya que el optimizador considera que al tener pocos registros es mas r\ufffdpido hacer un barrido que utilizar el \ufffdndice.<\/p>\n<p>Es recomendable hacer una actualizaci\ufffdn a las estad\ufffdsticas de los \ufffdndices como parte del mantenimiento de las bases de datos.<\/p>\n<p>Continuaremos en el siguiente post con los demas elementos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cuando te encuentras con la presi\u00f3n de entregar un producto en un tiempo determinado y, seamos sinceros, han pasado cosas que no estaban en el plan, de tal forma que llevas ya con retraso considerable, escribes c\u00f3digo que no es optimo del todo, funciona, si, pero no esta optimizado y como pasa frecuentemente, cuando es [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[2,3],"tags":[],"class_list":["post-202","post","type-post","status-publish","format-standard","hentry","category-trabajo","category-vida"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/posts\/202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/comments?post=202"}],"version-history":[{"count":2,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/posts\/202\/revisions"}],"predecessor-version":[{"id":264,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/posts\/202\/revisions\/264"}],"wp:attachment":[{"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/media?parent=202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/categories?post=202"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.joiz.net\/blog\/itzcoaltam\/wp-json\/wp\/v2\/tags?post=202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}