No usar el prefijo sp_al crear store procedure

Cualquier procedimientos almacenados con el prefijo ‘sp_’ primero se busca en la base de datos maestro en lugar de la que se ha creado. Esto provocará un retraso en el procedimiento almacenado.

Evaluar el uso de DISTINCT

Sólo debe usarse si sabemos que la query puede devolver duplicados, y además esto puede provocar un mal funcionamiento de la aplicación que hace uso de los datos.

La sentencia DISTINCT genera una gran cantidad de trabajo extra a SQL Server debido a que consume muchos recursos que son necesarios para otras queries que sean lanzadas dentro de la base de datos. Sólo se debe usar si es necesario.

Devolver los datos que se necesitan usando TOP

Para evitar en la aplicación de forma sencilla el retorno de cientos de registros o incluso miles es posible usar el operador TOP con una sentencia SELECT. De este modo se puede  ayuda a mejorar el rendimiento. ejemplo:

SELECT TOP 100 fname, lname FROM customers
WHERE state = ‘mo’

Esta query limita los resultados a las 100 primeras filas, incluso si el criterio del WHERE de devuelve 10000 registros.

El operador TOP también permite seleccionar porcentajes, tal y como indica el siguiente ejemplo:

SELECT TOP 10 PERCENT fname, lname FROM customers
WHERE state = ‘mo’

Uso de SET ROWCOUNT

El resultado de SET ROWCOUNT es el mismo que TOP, pero en algunos casos puede tener peor rendimiento cuando se trata con listas no ordenadas, por ello es preferible el uso de TOP.

Uso de operadores en el WHERE

Otro aspecto importante de cara a mejorar el rendimiento de las queries, es tener en consideración que operadores dentro de la clausula WHERE tienen mejor rendimiento, a continuación se detalla una lista ordenada de mejor a peor rendimiento:

  1. =
  2. >, >=, <, <=
  3. LIKE
  4. <>

Además de esto, existen otros criterios que son también importantes a la hora de elaborar la condición de cualquier Query. Estas consideraciones son relativas a que ciertos operadores pueden prestarse a tener mejor rendimiento según se usen, a continuación detallamos estos casos, ordenados de mayor a peor rendimiento:

  1. Un literal único en lugar de varios usado al lado de un operador
  2. Un nombre de columna o de parámetro al lado de un operador
  3. Una expresión multi-operando al lado de un operador
  4. Un número único exacto al lado de un operador
  5. Un número único no exacto al lado de un operador (date, time)
  6. Datos de caracteres, Null

En el caso de haber varias expresiones dentro del WHERE, no se agiliza el rendimiento por ordenarlos, excepto en algunos casos.

Uso de NOT IN

En el caso que tengamos que hacer uso del comando NOT IN tendremos que tener especial cuidado en su uso ya que posee un mal rendimiento ya que obliga al SQL Server Optmizer a realizar un SCAN, en su lugar mejor utilizaremos la siguientes opciones ordenadas de mejor a peor rendimiento:

  1. Usar EXISTS o NOT EXISTS
  2. Usar IN
  3. Realizar un LEFT OUTER JOIN y chequear por una condición NULL

Cuando exista la posibilidad de elegir entre IN o EXISTS utilizaremos siempre EXISTS, ya que tiene mejor rendimiento.

Mejores prácticas en el uso de LIKE

En el caso del comando LIKE es necesario entender que hay maneras más optimas en el uso de dicho comando. En el caso que nos trata del comando LIKE debemos en la medida de los posible usar una “leading character” esto es un carácter diferente de un “wildcard” (%,*, etc…).

Por ejemplo la query LIKE ‘%m’ tiene peor rendimiento que LIKE ‘m%’ ya que en el segundo caso (más optimo rendimiento).

Insercción de datos binarios de gran tamaño

Si nuestra aplicación necesita inserta insertar datos binarios de gran tamaño en una columna de datos, se debe realizar en primer lugar a través de un Store Procedure y no usar nunca una sentencia INSERT dentro de nuestra aplicación.

LA razón es ue la aplicación debe primero convertir los datos binarios en una cadena de caracteres (lo que hace doblar su tamaño incrementando el tráfico de red y llevando más tiempo) antes de que pueda ser enviada al servidor. Y cuando el servidor recibe la cadena de caracteres, tiene que convertirla de nuevo a datos binarios (llevandose aún más tiempo que en la primera conversión).

El uso de Store Procedures evita todo esto ya que la actividad ocurre en el servidor SQL Server y los datos transmitidos a través de la red son menores.

Concatenación ANDs

Si existe una cláusula WHERE que incluye expresiones conectadas por dos o más operadores AND, SQL Server evaluará desde la izquierda hacia la derecha en el orden que hayan sido escritas. Esto asume que no se hayan usado paréntesis para cambiar el orden de la ejecución. Por esta razón se debe considerar lo siguiente cuando usemos el operador AND:

  1. Localizaremos la expresión menos probable de suceder y la pondremos en primer lugar de la expresión AND. De este modo si una expresión AND es falsa la cláusula finalizará inmediatamente ahorrando tiempo
  2. Si ambas partes de una expresión AND son iguales o tienen igual peso, y son falsas, pondremos la menos compleja primero. De este modo si es falsa la expresión se realizará menos trabajo para evaluar la expresión.

Uso de ORDER BY

Usaremos ORDER BY en las QUERIES que lancemos sólo si es absolutamente indispensable, es decir, que si es posible realizar la ordenación en el lado del cliente siempre será mejor que realizarla desde el lado del servidor SQL Server.

En el caso que sea absolutamente necesario realizar la ordenación en el lado del servidor SQL Server, deberemos atender a las siguientes recomendaciones:

  1. Mantener el número de filas a ordenar al mínimo, haciendo esto mediante la devolución de aquellas filas que son absolutamente necesarias.
  2. Mantener el número de columnas a ordenar al mínimo. En otras palabras, no ordenar columnas no rqueridas.
  3. Mantener el ancho (tamaño físico) de las columnas a ordenar al mínimo
  4. Ordenar columnas con tipos de datos númericos en lugar de tipos de datos carácter

No usar el comando GROUP BY sin una función de agregación

La cláusula GROUP BY puede usarse con o sin una función de agregación. Pero si queremos obtener un mejor rendimiento, no usaremos la cláusula GROUP BY sin una función de agregación. Esto es porque produce el mismo resultado usar DISTINCT y es más rápido. Veamos un ejemplo:

USE Northwind
SELECT OrderID
FROM [Order Details]
WHERE UnitPrice > 10
GROUP BY OrderID

O

USE Northwind
SELECT DISTINCT OrderID
FROM [Order Details]
WHERE UnitPrice > 10

Ambas QUERIES dan el mismo resultado, pero la segunda obtendrá mejor rendimiento, ya que usa menos recursos.

¿Cómo acelerar la cláusula GROUP BY?

Para acelerar el uso de la cláusula GROUP BY debemos seguir las siguientes recomendaciones:

  1. Mantener el número de fílas a devolver por la QUERY tan pequeño como sea posible
  2. Mantener el número de agrupaciones tan limitado como sea posible
  3. No agrupar columnas redundantes
  4. Si hay un JOIN en la misma SELECT que tiene un GROUP BY, intentar reescribir la QUERY usado una SUBQUERY en lugar de usar un JOIN. Si es posible hacer esto, el rendimiento sera major. Si se tiene que usar un JOIN, intentaremos hacer el GROUP BY por columna desde la misma tabla que la columna o columnas sobre la cual la se usa la función.

Consideraremos el añadir un ORDER BY a la SELECT que ordena por la misma columna que el GROUP BY. Eso puede producir que el GROUP BY tenga mejor rendimiento.

DERIVED TABLES en lugar de TEMPORARY TABLES

En lugar de usar tablas temporales, usaremos tablas derivadas para mejorar el rendimiento de nuestra QUERY. Esto funciona de la siguiente forma:

SELECT num_Customer, dt_Date FROM (SELECT num_Customer, dt_Date, nom_Customer FROM Customers)

Con este tipo de tablas mejoramos el rendimiento de nuestra QUERY ya que se producen menos operaciones de I/O sobre el servidor.

Comprobar la existencia de un registro en una tabla

Si necesitamos verificar si un registro existe en una tabla no usaremos nunca SELECT COUNT (*) para identificarla ya que es muy ineficiente y utiliza recursos de servidor de forma masiva.

En su lugar la sentencia Transact-SQL IF EXISTS para determinar si el registro en cuestión existe que es mucho más eficiente. Por ejemplo:

Usando SELECT COUNT (*):

IF (SELECT COUNT(*) FROM table_name WHERE column_name = ‘xxx’)

Usando IF EXISTS (mucho más rápido):

IF EXISTS (SELECT * FROM table_name WHERE column_name = ‘xxx’)

La razón por la cual IF EXISTS es más rápido que SELECT COUNT (*) es porque en el momento que dicha QUERY encuentra el registro finaliza inmediatamente, mientras que COUNT(*) debe contar todas las filas.

FOREACH

La instrucción foreach repite un grupo de instrucciones incluidas en el bucle para cada elemento de una matriz o de un objeto collection.

mostrar el contenido de una matriz de enteros

int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray)
{  System.Console.WriteLine(i);
}

pasar filas seleccionadas de un datagridview a un datatable

dtDestino = new DataTable();
for (int nContador = 0; nContador <= (dataGridView1.Columns.Count – 1); nContador++)
{
dtDestino.Columns.Add(dataGridView1.Columns[nContador].HeaderText);
}
DataGridViewSelectedRowCollection aFilasSelec = dataGridView1.SelectedRows;
foreach (DataGridViewRow oFila in aFilasSelec)
{
DataRow row = dtDestino.NewRow();
foreach (DataGridViewCell oCelda in oFila.Cells)
{
row[oCelda.ColumnIndex] = oCelda.Value;
}
dtDestino.Rows.Add(row);
}

por cada tabla en el dataset imprime los valores de cada fila

private void PrintRows(DataSet dataSet)
{    foreach(DataTable thisTable in dataSet.Tables)
    {   foreach(DataRow row in thisTable.Rows)
        {   foreach(DataColumn column in thisTable.Columns)
            {    Console.WriteLine(row[column]);
            }
        }
    }
}

Create

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die('No puede conectarse: ' . mysql_error());
}
if (mysql_query("CREATE DATABASE mi_bd",$con))
{  echo "Crear Base de datos";
}
else
{  echo "Error al crear la base de datos: " . mysql_error();
}
mysql_select_db("mi_bd", $con);
$sql = "CREATE TABLE alumno
(
Nombres varchar(20),
Apellidos varchar(25),
Edad int
)";
mysql_query($sql,$con);
mysql_close($con);
?>

Insert

insertar datos de un formulario a una base de datos //crear el archivo archivo HTML y poner este codigo
<html>
<body>
<form action="insertar.php" method="post">
Nombres: <input type="text" name="Nombres" />
Apellidos: <input type="text" name="Apellidos" />
Edad: <input type="text" name="Edad" />
<input type="submit" />
</form>
</body>
</html>

//crear un archivo php "insertar.php"

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die('No puede conectarse: ' . mysql_error());
}
mysql_select_db("mi_bd", $con);
$sql="INSERT INTO alumno (Nombres, Apellidos, Edad) VALUES
('$_POST[Nombres]','$_POST[Apellidos]','$_POST[Edad]')";
if (!mysql_query($sql,$con))
{  die('Error: ' . mysql_error());
}
echo "1 fila agregada";
mysql_close($con)
?>

Select

Mostrar los datos en una tabla HTML
<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die("No puede conectarse: " . mysql_error());
}
mysql_select_db("mi_bd", $con);
$result = mysql_query("SELECT * FROM alumno");
echo "<table border=’1'>
<tr>
<th>Nombres</th>
<th>Apellidos</th>
<th>Edad</th>
</tr>";
while($row = mysql_fetch_array($result))
{ echo "<tr>";
  echo "<td>" . $row['Nombres'] . "</td>";
  echo "<td>" . $row['Apellidos'] . "</td>";
  echo "<td>" . $row['Edad'] . "</td>";
  echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>

Where

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die('No puede conectarse: ' . mysql_error());
}
mysql_select_db("mi_bd", $con);
$result = mysql_query("SELECT * FROM alumno WHERE Nombres='Jean Paul'");
while($row = mysql_fetch_array($result))
{ echo $row['Nombres']." | ".$row['Apellidos']." | ".$row['Edad'];
  echo "<br />";
}
?>

Order By

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die('No puede conectarse: ' . mysql_error());
}
mysql_select_db("mi_bd", $con);
$result = mysql_query("SELECT * FROM alumno ORDER BY Nombres");
while($row = mysql_fetch_array($result))
{ echo $row['Nombres'];
  echo " " . $row['Apellidos'];
  echo " " . $row['Edad'];
  echo "<br />";
}
mysql_close($con);
?>

Update

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{ die('No puede conectarse: ' . mysql_error());}
mysql_select_db("mi_bd", $con);
mysql_query("UPDATE alumno SET Edad = '20'
WHERE Nombres = 'jean paul' AND Apellidos = 'zuniga maradiegue'");
mysql_close($con);
?>

Delete

<?php
$con = mysql_connect("localhost","root","");
if (!$con)
{  die('No puede conectarse: ' . mysql_error());
}
mysql_select_db("mi_bd", $con);
mysql_query("DELETE FROM alumno WHERE Nombres='ana'");
mysql_close($con);
?>

Devolver el identificar del ultimo Insert

n caso que se necesite el ID del último ingresado para relacionarlo con otra tabla, se utilizar la función de PHP mysql_insert_id(); para esto la tabla que se inserta debe tener un id de valor AUTO_INCREMENT de tipo INT.

<?php
$link = mysql_connect(‘localhost’, ‘mysql_user’, ‘mysql_password’);
if (!$link) {
die(‘No puede conectarse: ‘ . mysql_error());
}
mysql_select_db(‘mydb’);
mysql_query(“INSERT INTO producto (descripcion) values (‘lapiz’)”);
printf(“El identificador del ultimo insert %d\n”, mysql_insert_id());
?>

Encriptar Contraseña con md5 y sha1

Se recomienda usar Sha1 por ser más segura.

<?php
$password = "123456";
echo ("El password con MD5: ". md5($password)) ."</br>";
echo ("El password con SHA1: ". sha1($password));
?>

Contador de visitas

El archivo contador.txt debe iniciar con el valor 0 en la primera linea (no presiones la tecla Enter).

<?php
$archivo = "contador.txt";
$contador = 0;
$fp = fopen($archivo,"r");
$contador = fgets($fp,26);
fopen($fp);
++$contador;
$fp = fopen($archivo,"w+");
fwrite($fp,$contador, 26);
fclose($fp);
echo"Esta pagina ha sido visitada ".$contador." veces";
?>

Caracteristicas de Cooperator Framework

  • Modelo totalmente tipado, esto significa que las clases de persistencia y recuperacion de objetos devuelven un tipo especifico y no un tipo object.
  • Debido a la potencia de VS2005 se pueden bindear estos objetos a los controles sin escribir una linea de codigo, y aprovechar las venjas de edicion de VS2005.
  • No depende de la estructura relacional, soporta cualquier tipo de estructura de base de datos.
  • No hay que modificar la Primary Key o crear un campo unique en las tablas.
  • Generador de Store Procedure.
  • Soporta concurrencia.
  • Las condiciones de busqueda se expresan mediante objetos especificos.
  • tipados y extendibles por el programador que terminan ejecutando un Stored Procedure en forma transparente.
  • En la capa de negocio todo se expresa en terminos del dominio, incluido los filtros y busquedas.
  • Genera codigo en C# o VB.
  • Hay un modelo propuesto de las clases que se generaran que se basa en el modelo de datos, pero el programador, antes de generar las clases edita dicho modelo en una herramienta muy facil de usar y define como sera el modelo que desea crear.
  • Si las opciones de modelado que provee la herramienta no alcanzan, el programador puede editar los templates y generar su propio modelo.
  • Si mas tarde se agrega un nuevo campo a una tabla, se puede volver a generar.
  • Soporta transacciones desconectadas.
  • Codigo abierto en C#.

Enlaces de Interes

Kumbia PHP Framework

Kumbia es un framework destinado a la creación de software y sitios web utilizando la arquitectura MVC y otros patrones de programación como ActiveRecord y TemplateView. Altamente integrado con AJAX facilita la creación de sitios Web 2.0.

Caracteristicas de Kumbia Framework

  • Arquitectura MVC (Modelo, Vista, Controlador).
  • Orientado a Objetos con PHP5.
  • Validación de Formularios.
  • Plantillas ( Template View ).
  • Administración de Cache.
  • Generadores de Formularios CRUD (Crear, Obtener, Actualizar y Borrar).
  • AJAX y Efectos Visuales.
  • Seguridad.
  • PHPMailer: Correo Electrónico.
  • Smarty: Motor de Plantillas potente y fácil de usar.
  • Reportes PDF.
  • Es compatible con MySQL, PostgreSQL, Oracle.
  • y mucho más.

Enlaces de Interes

videos de kumbia y un ejemplo usando kumbia

http://astro.gsol.biz/kumbia/Tienda%20-%20Parte%201.zip
http://astro.gsol.biz/kumbia/Tienda%20-%20Parte%202.zip
http://astro.gsol.biz/kumbia/Tienda%20-%20Parte%203.zip
http://astro.gsol.biz/kumbia/tienda.zip

Kumbia vs Cake vs Symfony
http://minombreesfelipe.blogspot.com/

sistema de biblioteca hecho con kumbia
http://atenea.unicauca.edu.co/~wpantoja/index.php?entry=entry080116-085824

grupo activo de kumbia Framework
resgistrate en : http://groups.google.com/group/kumbia
en la seccion archivos se puede descargar la version 0.5 con el nombre : “05.zip”
y tambien puedes descargar el manual del desarrollador “Kumbia Paper.pdf”

* si le ha parecido de utilidad deje su comentario. *

MySQL soporta distintas tecnologías de almacenamiento de datos, entre estas destacan MyISAM e InnoDB. El primero de ellos, MyISAM, es el utilizado por defecto, y es recomendable para aplicaciones en las que dominan las sentencias SELECT sobre los INSERT / UPDATE. La característica principal de InnoDB es que soporta transacciones de tipo ACID (Atomicity, Consistency, Isolation and Durability), bloqueo de registros e integridad referencial. El mito de que MyISAM es siempre más rápido que InnoDB en lecturas no parece ser cierto siempre.