Eu tenho pesquisado o uso de SQL_BUFFER_RESULT. Principalmente, é referido como uma ajuda para reduzir os problemas de bloqueio de tabela.
Parece ser uma boa opção para usar.
No entanto, não consigo encontrar nenhuma desvantagem nisso. É uma opção que deve ser usada na maioria das vezes?
SQL_BUFFER_RESULT
cria uma tabela temporária no servidor para cada conjunto de resultados. Esta não é uma tabela temporária comoCREATE TEMPORARY TABLE
- é uma tabela temporária implícita, como seria criada ao usar uma cláusula GROUP BY ou com uma subconsulta. Como tal, todas as mesmas regras se aplicam .Primeiramente, vamos falar do problema que
SQL_BUFFER_RESULT
se pretende resolver:Quando o cliente solicita dados do servidor, até que todo o conjunto de resultados tenha sido transmitido ao cliente, a consulta ainda está "em execução" e alguns bloqueios ainda podem ser mantidos. Enquanto os dados estão sendo transmitidos, eles aparecerão no
Sending data
estado. Depende da biblioteca se o cliente apenas obtém todos os dados de uma vez quando a consulta é executada ou se eles vão aparecendo conforme você seleciona as linhas, mas um exemplo de problema é o seguinte:Obviamente artificial, mas no caso acima, se houver 1.000 linhas, a consulta ainda será executada ativamente por 10.000 segundos. Isso pode parecer muito improvável, mas muitos aplicativos têm "tempo de reflexão" entre a busca de cada linha porque eles fazem algum processamento. Isso é "uma coisa muito ruim de se fazer". Outro caso em que esse tipo de efeito de gotejamento pode ocorrer é com um grande conjunto de resultados em uma conexão lenta. Em última análise, o problema é o fluxo de dados para o cliente, fazendo com que a consulta permaneça em um estado ativo.
SQL_BUFFER_RESULT
resolve esse problema armazenando primeiro o resultado em uma tabela temporária, o que faz com que a consulta termine mais rapidamente, liberando todos os seus bloqueios (que bloqueios?). O conjunto de resultados é então alimentado ao cliente a partir da tabela temporária em vez da própria consulta.Isso parece ótimo!
Mas...
SQL_BUFFER_RESULT
literalmente faz com que todas as consultas incluam "Usando temporário" (quase) o tempo todo. Meu pequeno teste mostrou que havia casos em que o MySQL não usava uma tabela temporária mesmo com essa dica, mas eles eram limitados (pesquisas de linha única na chave primária pareciam ser o único caso).Aqui estão alguns exemplos para mostrar o efeito:
Para que serve o problema que está sendo resolvido? "fechaduras". Como esta é uma dica para consultas SELECT, a menos que você esteja usando FOR UPDATE ou LOCK IN SHARED MODE, há muito poucos bloqueios feitos em leituras de qualquer maneira e eles são muito rápidos, então você está resolvendo principalmente um problema que não existe. Exceções sempre existem, mas a sobrecarga de criar uma tabela temporária para quase todas as consultas superará em muito qualquer benefício obtido ao fazer com que os bloqueios desapareçam mais rapidamente.
A recomendação do MySQL é usar a
SQL_BUFFERED_RESULT
dica ao recuperar um conjunto de resultados muito grande em uma conexão de rede para o cliente. Não consigo ver nenhum valor em usá-lo em outro contexto.Dito isso, você pode testar e definir isso "globalmente" definindo sql_buffer_result =1 no início de cada sessão. Em um ambiente com qualquer simultaneidade, eu prevejo resultados ruins.