Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Busquedas muy lentas con like %palabra%

Estas en el tema de Busquedas muy lentas con like %palabra% en el foro de Mysql en Foros del Web. Hola amigos tengo una base de datos de mas de 500 mil registros y uso una busqueda del siguiente modo. id(int) auto_increment ruc(int) int (indice) ...
  #1 (permalink)  
Antiguo 28/08/2008, 08:46
Avatar de kernelcom-com  
Fecha de Ingreso: mayo-2008
Ubicación: Lima
Mensajes: 216
Antigüedad: 15 años, 11 meses
Puntos: 3
Busquedas muy lentas con like %palabra%

Hola amigos tengo una base de datos de mas de 500 mil registros y uso una busqueda del siguiente modo.

id(int) auto_increment
ruc(int) int (indice)
nombre(varchar) indice

cuando hago la consulta con where ruc=76786876 por ejemplo hace la busqueda demasiado rapida, y excelente,

Pero cuando intento esto : where nombre like '%palabra%' me hace la busqueda un poquito lenta hasta 2 o 3 segunfos y es demasiado.

Me han dicho que hay otras formar, agradecere sus respuestas.
saludos amigos.
  #2 (permalink)  
Antiguo 28/08/2008, 08:51
 
Fecha de Ingreso: noviembre-2007
Mensajes: 38
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Busquedas muy lentas con like %palabra%

Hola, podes optar por dos cosas, la primera es usar un sistema de cache, el recomendado es memcached, basicamente checheara lo que vos quieras, en tu caso guardaras la el resultado de la consulta.

La otra opcion es usar un programilla que se ocupa de realizar buquedas de forma optima;
http://www.sphinxsearch.com/

Tambien podrias combinar los dos, y tambien cacher tus paginas webs, para que no sea necesario que se generen constantemente.

Saludos
  #3 (permalink)  
Antiguo 28/08/2008, 11:13
Avatar de kernelcom-com  
Fecha de Ingreso: mayo-2008
Ubicación: Lima
Mensajes: 216
Antigüedad: 15 años, 11 meses
Puntos: 3
Respuesta: Busquedas muy lentas con like %palabra%

Gracias por responder, pero no encuentro nada en el link q me mandaste, ahgradesco otras respuestas.

saludos y una ayuda o un query para consultar mas rapido gracias por su ayuda
  #4 (permalink)  
Antiguo 29/08/2008, 18:10
Avatar de xcars  
Fecha de Ingreso: mayo-2005
Ubicación: El Salvador
Mensajes: 753
Antigüedad: 18 años, 11 meses
Puntos: 4
Respuesta: Busquedas muy lentas con like %palabra%

Pues mira, puedes usar indices fulltext pero tienes que considerar que tu tabla tiene que ser myisam y los inserts y updates se tardan mas de lo normal por este tipo de indices....
__________________
Con Microaplicaciones puedes hacer tu tienda en línea de forma sencilla y rápida, sin costos ocultos y con mucha responsabilidad.
  #5 (permalink)  
Antiguo 31/08/2008, 07:17
Avatar de kernelcom-com  
Fecha de Ingreso: mayo-2008
Ubicación: Lima
Mensajes: 216
Antigüedad: 15 años, 11 meses
Puntos: 3
Respuesta: Busquedas muy lentas con like %palabra%

gracias solucione mi problema.
saludos
  #6 (permalink)  
Antiguo 31/08/2008, 08:43
Avatar de Yaraher  
Fecha de Ingreso: abril-2007
Ubicación: Lima, Perú
Mensajes: 262
Antigüedad: 17 años
Puntos: 9
Respuesta: Busquedas muy lentas con like %palabra%

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.
  #7 (permalink)  
Antiguo 31/08/2008, 22:15
Avatar de kernelcom-com  
Fecha de Ingreso: mayo-2008
Ubicación: Lima
Mensajes: 216
Antigüedad: 15 años, 11 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 ){ 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->ConsultaCOUNT0"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 && $_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] < :
                
$_GET[pag] = ;
                break ;
            case 
$_GET[pag] > $this->total_pag :
                
$_GET[pag] = $this->total_pag ;
        }
        
$desde ereg('[0-9]+',$_GET[pag]) ? ($_GET[pag] - 1) * $this->mostrar ;
        
$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 ;
        
$url $this->url() ;
        
$pag_anterior $_GET[pag] - ;
        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 ;
        }
        
$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] + ;
        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()


?>
  #8 (permalink)  
Antiguo 02/09/2008, 09:20
 
Fecha de Ingreso: abril-2001
Mensajes: 293
Antigüedad: 23 años
Puntos: 0
Respuesta: Busquedas muy lentas con like %palabra%

Estimado, veo que tu problema no iva por el lado de la optimizacion, ya que segun el codigo que posteas te faltaba paginar los resultados, pudiste haber probado aplicando un limit 10 a tu consulta, quizas te convenga cambiar el diseño de tu aplicacion, es decir:

si quieres buscar por nombre, crear una lista de sugerencia estilo mootools, cuando seleccione el nombre, rescatas el rut y realizas la consulta rapido por la primary.


saludos
  #9 (permalink)  
Antiguo 02/09/2008, 10:25
Avatar de BrujoNic
Super Moderador
 
Fecha de Ingreso: noviembre-2001
Ubicación: Costa Rica/Nicaragua
Mensajes: 16.935
Antigüedad: 22 años, 5 meses
Puntos: 655
Respuesta: Busquedas muy lentas con like %palabra%

Tema cerrado, esta es una sección de Base de Datos y NO de programación.

Por favor, lee lo siguiente:
http://www.forosdelweb.com/f21/funci...-datos-413499/
__________________
La tecnología está para ayudarnos. No comprendo el porqué con esa ayuda, la gente escribe TAN MAL.
NO PERDAMOS NUESTRO LINDO IDIOMA ESPAÑOL
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Tema Cerrado




La zona horaria es GMT -6. Ahora son las 08:59.