haidan 0 Denunciar post Postado Junho 5, 2014 Boa noite a todos! Como vão? Bom, estou com um problema de baixo desempenho no retorno de um SELECT. Está demorando muito. Eis aqui o meu select com valores fictícios (caso não tenham tempo para visualizar o código que monta ele): select * from perguntas, relacoes where perguntas.statusPergunta = 1 and relacoes.codCategoria IN (select codCategoria from categoria) and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codLocal = 7) and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codIntimidade = 3) and perguntas.codPergunta = relacoes.codPergunta order by RAND() limit 1 aqui a montagem do meu select: <?php header("Content-Type: text/html; charset=ISO-8859-1",true) ?> <?php session_start(); include_once 'manage/conexao.php'; $local = $_SESSION['local']; $categorias = $_SESSION['categorias']; $intimidade = $_SESSION['intimidade']; //-----VALORES FICTÍCIOS------ $local = "7"; $categorias = "all"; //SEMPRE QUE O VALOR DE CATEGORIAS É "all" O SELECT DEMORA A RETORNAR, PORÉM, CASO FOR UM ARRAY COM POUCOS NÚMEROS O SELECT RETORNA RAPIDAMENTE $intimidade = "3"; //---------------------------- $qstr = ""; $qlocal = ""; $qintimidade = ""; //--------CHECA SE FOI DEFINIDO VALOR PARA LOCAL-------------------- if($local != "all"){ $qlocal = "and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codLocal = $local)"; } //nesse caso, RESULTA EM $qlocal = "and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codLocal = 7)"; //-------------CHECA SE FOI DEFINIDO VALOR PARA INTIMIDADE------------------- if($intimidade != "all"){ $qintimidade = " and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codIntimidade = $intimidade)"; } //nesse caso, RESULTA EM $qintimidade = "and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codIntimidade = 3)"; //CHECA SE FORAM DEFINIDOS VALORES PARA CATEGORIA //CASO SIM, CRIA UMA VERIFICAÇÃO PARA CADA VALOR, SEPARADOS POR "OR" if($categorias != "all"){ $qstr.= "and ("; for($i = 0; $i < count($categorias)-1; $i++){ $qstr.= "relacoes.codCategoria = ".$categorias[$i]; if($i + 2 < count($categorias)){ $qstr.= " or "; } } $qstr.= ")"; }else{ $qstr.= "and relacoes.codCategoria IN (select codCategoria from categoria)"; } //nesse caso, RESULTA EM $qstr = "and relacoes.codCategoria IN (select codCategoria from categoria)"; $query = mysql_query("select * from perguntas, relacoes where perguntas.statusPergunta = 1 $qstr $qlocal $qintimidade and perguntas.codPergunta = relacoes.codPergunta order by RAND() limit 1") or die(mysql_error()); //------------QUERRY FINAL:---------------------------------------------------------------------------------------- //"select * from perguntas, relacoes // where perguntas.statusPergunta = 1 // and relacoes.codCategoria IN (select codCategoria from categoria) // and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codLocal = 7) // and perguntas.codPergunta IN (select relacoes.codPergunta from relacoes where relacoes.codIntimidade = 3) // and perguntas.codPergunta = relacoes.codPergunta // order by RAND() limit 1" //----------------------------------------------------------------------------------------------------------------- while($ob = mysql_fetch_object($query)){ $pergunta = $ob->dscPergunta; } echo $pergunta; mysql_close($conexao); ?> Estrutura da tabela relacoes: codRelacao(int) pk codPergunta(int) codLocal(int) codCategoria(int) codIntimidade(int) possui cerca de 12mil registros (um para cada ligação do codPergunta com os demais) O que eu poderia fazer para melhorar isso? Obrigado pela atenção, abraço! Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 6, 2014 Estes IN do primeiro select são desnecessários , qual o motivo deles !? Compartilhar este post Link para o post Compartilhar em outros sites
haidan 0 Denunciar post Postado Junho 6, 2014 Estes IN do primeiro select são desnecessários , qual o motivo deles !? Sim. Eu havia colocado pois percebi que quando havia participação da parte de categorias na query o retorno era mais rápido. Mas obviamente não adiantou nada, hehe. Acabei deixando, esqueci de tirar mesmo. Estou dividindo a tabela relacoes em outras três: per_local //relacionando a pergunta com os locais per_categoria //relacionando a pergunta com as categorias per_intimidade //relacionando a pergunta com a intimidade Com isso, o select vai ficar assim: $misc = "SELECT dscPergunta from perguntas, p_local, p_categoria, p_intimidade where perguntas.statusPergunta = 1 " . "and perguntas.codPergunta = p_categoria.codPergunta " . "and (p_categoria.codCategoria = 5 or p_categoria.codCategoria = 7) " . "and perguntas.codPergunta = p_local.codPergunta " . "and p_local.codLocal = 1 " . "and perguntas.codPergunta = p_intimidade.codPergunta " . "and p_intimidade.codIntimidade = 3"; Será que melhora? abraço Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Junho 6, 2014 http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html Analise o Plano de Execução da query. Compartilhar este post Link para o post Compartilhar em outros sites
haidan 0 Denunciar post Postado Junho 6, 2014 Boa noite, resolvi o problema fazendo o que descrevi acima. Obrigado pela atenção! baraço Compartilhar este post Link para o post Compartilhar em outros sites