Ver Mensaje Individual
  #7 (permalink)  
Antiguo 31/08/2008, 22:15
Avatar de kernelcom-com
kernelcom-com
 
Fecha de Ingreso: mayo-2008
Ubicación: Lima
Mensajes: 216
Antigüedad: 18 años, 4 meses
Puntos: 3
Respuesta: Busquedas muy lentas con like %palabra%

Cita:
Iniciado por Yaraher Ver Mensaje
Podrías indicar que fue lo que hiciste para resolver el problema; puede ser de ayuda para otros que tengan problemas de optimización de DB. Una opción, como ya dijeron, es crear un índice en el campo de esa búsqueda.
LO solucione con estos dos archivos los comparto para uds.
class.busqueda.php
Código PHP:
<?php

if(!$con = @mysql_connect("localhost", "root", 'pass'))
{echo
"Sin conexion a la Base de Datos";
} 
mysql_select_db("c2",$con);    


class 
Paginacion {

    var 
$TotalResultados = "";

    var 
$PaginaActual;

    var 
$Busqueda = "";

    var 
$TablaBusqueda = "";

    var 
$Consulta;

    var 
$Seleccion_Campos = "";

    var 
$MostrarResultados = "";

    var 
$Listado;

    var 
$Seleccion;

    var 
$pag;

        var 
$indice=0;



    function 
ContabilizarCadena()
    {    
        
$this->Fracciones = explode(" ", $this->Busqueda);  
        
$this->Fracciones = count($this->Fracciones); 

        if(
$this->Fracciones > 1 ){ return("Busqueda_Against");  } else { return false; }
    }

    

 function 
Agregar_Columna($Array){

      
$this->Listado[$this->indice] = $Array;
      
$this->indice++;

       }


   function 
Listar_Columna_DB(){

       foreach(
$this->Listado as $valor){
            
$Valores .= $valor.",";
         }

    return 
substr($Valores,0,-1);
    
   }



    function 
Ablucion($Consulta)
    {
            
$Consulta = htmlspecialchars(trim(addslashes(stripslashes($Consulta))));
            
$Consulta = str_replace(chr(160),'',$Consulta);
            
$Consulta = mysql_real_escape_string($Consulta);
            return(
"$Consulta");
    }



   function 
Ordenar_Columna_LIKE(){


    if(
count($this->Listado) == 0){
    
    
$this->Seleccion_Campos = "     ";

    }
    else {

        
$this->Seleccion_Campos = "WHERE ";

    foreach(
$this->Listado as $valor){

            
$this->Seleccion_Campos .= $valor." LIKE '%" .  $this->Ablucion($this->Busqueda)  . "%' OR ";

    }
}

return 
substr($this->Seleccion_Campos,0,-4);
    
   }

    function 
_Pag(){

    (!empty(
$_GET['pag']) && eregi("^[0-9]+$",$_GET['pag'])) ? ( $this->pag = $_GET['pag'] ) : ( $this->pag = 1) ;

    return(
$this->pag);

    }


    function 
PaginaInicial(){



    if(!
eregi("^[0-9]+$",$this->MostrarResultados)) { $this->MostrarResultados = '10'; }
    return ((
$this->MostrarResultados*$this->_Pag())-$this->MostrarResultados);


    }



    function 
Consulta_LIKE(){

    if(!
eregi("^[0-9]+$",$this->MostrarResultados)) { $this->MostrarResultados = '10'; }

$this->Consulta  = "select " .  $this->Seleccion  . " from " .  $this->TablaBusqueda  . " ";
$this->Consulta .= "" .  $this->Ordenar_Columna_LIKE()  . " ";
$this->Consulta .= "order by id desc limit " . $this->PaginaInicial() . ","  . $this->MostrarResultados .  ""; 

return(
$this->Consulta);

    }


    function 
Consulta_MATCH_AGAINST(){

$this->Consulta  = "select " .$this->Seleccion. ", MATCH(".$this->Listar_Columna_DB().") ";
$this->Consulta .= "AGAINST('+".str_replace(" ","+",$this->Ablucion($this->Busqueda))."' IN BOOLEAN MODE) AS Score from  ";
$this->Consulta .= "".$this->TablaBusqueda." where MATCH(".$this->Listar_Columna_DB().") ";
$this->Consulta .= "AGAINST('+".str_replace(" ","+",$this->Ablucion($this->Busqueda))."' IN BOOLEAN MODE) ";
$this->Consulta .= "order by Score desc limit " . $this->PaginaInicial() . ","  . $this->MostrarResultados .  ""; 


return(
$this->Consulta);

    }
    





function 
Consulta_COUNT()
{

        if(!empty(
$this->Seleccion)){ 
                
$this->ExtraerP = explode(",",$this->Seleccion); 
                
$this->Extraer = $this->ExtraerP['0']; 
        } else { 
$this->Extraer = "*";}


if(
$this->ContabilizarCadena()){
$this->Consulta_Cadena = "" .  $this->TablaBusqueda  . " where MATCH(".$this->Listar_Columna_DB().") AGAINST('".$this->Busqueda."' IN BOOLEAN MODE)";
}else {
$this->Consulta_Cadena = "" .  $this->TablaBusqueda  . " " .  $this->Ordenar_Columna_LIKE()  . "";
}

$this->ConsultaCOUNT = mysql_query("select count(" . $this->Extraer . ") as Contar from " .  $this->Consulta_Cadena  . "");
$this->ConsultaCOUNT = mysql_result($this->ConsultaCOUNT, 0, "Contar");

return (
$this->ConsultaCOUNT);


}
    function 
_TotalREsultados(){
    
$this->TotalResultados = ceil($this->Consulta_COUNT()/$this->MostrarResultados);

    return(
$this->TotalResultados);    

    }


    function 
BusquedaSQL()
    {
    if(
$this->ContabilizarCadena()){
    return(
$this->Consulta_MATCH_AGAINST()); 
    } else {
    return(
$this->Consulta_LIKE()); 
    }
    }


    function 
_GET() {
        foreach (
$_GET as $nombre => $valor) {
            if (
$nombre != 'pag') {
                
$valor = urlencode($valor) ;
                
$url .= "$nombre=$valor&" ;
            }
        }
        return 
$_SERVER['PHP_SELF']."?".$url ;
    }



    function 
_Siguiente(){
    
    if(
$this->_TotalREsultados() > $this->_Pag()){
    
$this->Siguiente  = " <a href='".$this->_GET()."pag=".($this->_Pag()+1)."'>Siguiente >></a> ";
    
$this->Siguiente .= " <a href='".$this->_GET()."pag=".$this->_TotalREsultados()."'>Último ></a> ";
    } else {
        
$this->Siguiente = " Siguiente >> ";
        
$this->Siguiente .= " Último > ";
    }

    

        return(
$this->Siguiente);

    }

    function 
_Anterior(){
    
    if(
$this->_Pag() > "1"){
    
$this->Anterior  = " <a href='".$this->_GET()."pag=1'>< Inicial</a> ";
    
$this->Anterior  .= " <a href='".$this->_GET()."pag=".($this->_Pag()-1)."'><< Anterior</a> ";

    } else {
        
$this->Anterior = " < Inicial ";
        
$this->Anterior .= " << Anterior ";

    }
        return(
$this->Anterior);

    }

function 
_Imprimir_Paginacion()
{

    echo 
$this->_Anterior();
    
    for(
$_pag = ($this->_Pag() - 10); $_pag < $this->_Pag() + 10; $_pag++){

    if(
$_pag > 0 && $_pag <= $this->_TotalREsultados()){

    if(
$this->_Pag() == $_pag){
        echo 
" <b>".$_pag."</b>";
    } else {

        echo 
" <a href='".$this->_GET()."pag=".$_pag."'>".$_pag."</a> ";
    }



    } 

    }
    echo 
$this->_Siguiente();


}




        } 
# Fin Class




$objeto = new Paginacion;

$objeto->Seleccion = 'id,name,text';
$objeto->TablaBusqueda = "chat";
$objeto->Agregar_Columna('name');
$objeto->Agregar_Columna('text');
$objeto->Busqueda = $_GET['q'];
$objeto->MostrarResultados = "10";


echo 
$objeto->BusquedaSQL();



echo 
"<br ><br />";

$result = mysql_query($objeto->BusquedaSQL()); 

While(
$Datos = mysql_fetch_array($result) ) 
{ 
echo 
$Datos['name']." - ".$Datos['id']." - ".$Datos['text']." <br>  ";
} 

echo 
"<br ><br />";

$objeto->_Imprimir_Paginacion();


?>

paginar.php

Código PHP:
<?

class paginar {
    
# Obtener el total de resultados
    
function mostrar($a) {
        
$this->mostrar = $a ;
    }
    function 
paginar($a) {
        
$this->codigo = $a ;
        
$con = mysql_query(eregi_replace('select (.+) from','select count(*) from',$this->codigo)) ;
        
$this->total_resultados = mysql_result($con,0,0) ;
    }
    
# Procesar el código SQL
    
function procesar_codigo() {
        
$this->total_pag = ceil($this->total_resultados/$this->mostrar) ;
        switch(
true) {
            case 
$_GET[pag] < 1 :
                
$_GET[pag] = 1 ;
                break ;
            case 
$_GET[pag] > $this->total_pag :
                
$_GET[pag] = $this->total_pag ;
        }
        
$desde = ereg('[0-9]+',$_GET[pag]) ? ($_GET[pag] - 1) * $this->mostrar : 0 ;
        
$con = mysql_query($this->codigo." limit $desde,$this->mostrar") ;
        return 
$con ;
    }
    
# Crear la URL evitando repetir varias veces la variable de página (ej. index.php?id=noticias&n=1&pag=1)
    
function url() {
        foreach (
$_GET as $nombre => $valor) {
            if (
$nombre != 'pag') {
                
$valor = urlencode($valor) ;
                
$url .= "$nombre=$valor&" ;
            }
        }
        return 
$url ;
    }
    function 
crear_paginas() {

        if(
strstr($_SERVER[PHP_SELF],'/index.php')) {
            
$_SERVER[PHP_SELF] = str_replace('/index.php','/',$_SERVER[PHP_SELF]) ;
        }
        
$max_paginas = 8 ;
        
$url = $this->url() ;
        
$pag_anterior = $_GET[pag] - 1 ;
        if(
$pag_anterior >= 1) {
            
$paginas[] = "<a href=\"$_SERVER[PHP_SELF]?$url"."pag=1\" >Primera</a>" ;
            
$paginas[] = "<a href=\"$_SERVER[PHP_SELF]?$url"."pag=$pag_anterior\" >«</a>" ;
        }
        if(
$this->total_pag > $max_paginas) {
            
$this->total_pag_mostrar = $max_paginas ;
        }
        else {
            
$this->total_pag_mostrar = $this->total_pag ;
        }
        
$pag_desde = ($_GET[pag]-$max_paginas/2) ;
        if(
$pag_desde < 1) {
            
$pag_desde = 1 ;
        }
        
$pag_hasta = ($_GET[pag]+$max_paginas/2) ;
        if(
$pag_hasta > $this->total_pag) {
            
$pag_hasta = $this->total_pag ;
        }
        for(
$a = $pag_desde ; $a <= $pag_hasta ; $a++) {
            
$paginas[] = ($a != $_GET[pag]) ? "<a href=\"$_SERVER[PHP_SELF]?$url"."pag=$a\" >$a</a>" : $a ;
        }
        
$pag_siguiente = $_GET[pag] + 1 ;
        if(
$pag_siguiente <= $this->total_pag) {
            
$paginas[] = "<a href=\"$_SERVER[PHP_SELF]?$url"."pag=$pag_siguiente\" >»</a>" ;
            
$paginas[] = "<a href=\"$_SERVER[PHP_SELF]?$url"."pag=$this->total_pag\" >Ultima</a>" ;
        }
        
$paginas =
        
'<table width="100%" border="0" cellpadding="0" cellspacing="0">
        <tr>
        <td>Páginas: <b>'
.$this->total_pag.'</b></td>
        <td><div align="right">'
.@implode(', ',$paginas).'</div></td>
        </tr>
        </table>
        ' 
;
        echo 
$paginas ;
    }
}





        
$paginar = new paginar("select * from usuarios order by id") ;
        
# --> Número de resultados a mostrar
        
$paginar->mostrar("40") ;
        
$con = $paginar->procesar_codigo() ;
        while(
$datos = mysql_fetch_array($con)){



}

$paginar->crear_paginas()


?>