Inquerir:
SELECT COUNT(online.account_id) cnt from online;
Mas a tabela on-line também é modificada por um evento, com tanta frequência que consigo ver o bloqueio executando show processlist
.
Existe alguma gramática no MySQL que possa fazer com que a instrução select não cause bloqueios?
E eu esqueci de mencionar acima que está em um banco de dados escravo do MySQL.
Depois que eu adicionei no my.cnf:transaction-isolation = READ-UNCOMMITTED
escravo vai encontrar com erro:
Erro 'O registro binário não é possível. Mensagem: O nível de transação 'READ-UNCOMMITTED' no InnoDB não é seguro para o modo de log de bin 'STATEMENT' 'na consulta
Então, existe uma maneira compatível de fazer isso?
Respostas:
Encontrou um artigo intitulado "MYSQL WITH NOLOCK"
https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx
No MS SQL Server, você faria o seguinte:
e o equivalente MYSQL é
EDITAR
Michael Mior sugeriu o seguinte (dos comentários)
fonte
SESSION
e, portanto, o nível de transação se aplica apenas à próxima transação. Em seguida, basta substituir a terceira declaração acima porCOMMIT
. Nesse caso, será um noop, mas terá o efeito colateral de encerrar a transação e redefinir para o nível de isolamento padrão.SET TRANSACTION
estado da instrução : "Esta declaração define o nível de isolamento da transação, usado para operações nas tabelas do InnoDB".Se a tabela for InnoDB, consulte http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html - ela usa leitura consistente (modo sem bloqueio) para SELECTs "que fazem não especifique FOR UPDATE ou LOCK IN SHARE MODE se a opção innodb_locks_unsafe_for_binlog estiver configurada e o nível de isolamento da transação não estiver configurado como SERIALIZABLE. Portanto, nenhum bloqueio será definido nas linhas lidas da tabela selecionada ".
fonte
Usar
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
Os documentos da versão 5.0 estão aqui .
Os documentos da versão 5.1 estão aqui .
fonte
Você pode querer ler esta página do manual do MySQL. Como uma tabela é bloqueada depende de que tipo de tabela é.
O MyISAM usa bloqueios de tabela para obter uma velocidade de leitura muito alta, mas se você tiver uma instrução UPDATE aguardando, os SELECTS futuros ficarão na fila atrás do UPDATE.
As tabelas do InnoDB usam o bloqueio no nível da linha, e você não terá a tabela inteira bloqueada atrás de um UPDATE. Existem outros tipos de problemas de bloqueio associados ao InnoDB, mas você pode achar que ele se adapta às suas necessidades.
fonte
Dependendo do tipo da sua mesa, o bloqueio terá um desempenho diferente, mas o mesmo ocorrerá com uma contagem SELECT. Para tabelas MyISAM, uma simples tabela SELECT count (*) FROM não deve bloquear a tabela, pois acessa metadados para obter a contagem de registros. O Innodb levará mais tempo, pois precisa pegar a tabela em um instantâneo para contar os registros, mas não deve causar o bloqueio.
Você deve pelo menos ter o concurrent_insert definido como 1 (padrão). Então, se não houver "lacunas" no arquivo de dados para a tabela preencher, as inserções serão anexadas ao arquivo e SELECT e INSERTs podem ocorrer simultaneamente com as tabelas MyISAM. Observe que a exclusão de um registro coloca uma "lacuna" no arquivo de dados que tentará ser preenchida com inserções e atualizações futuras.
Se você raramente excluir registros, poderá definir concurrent_insert como 2 e as inserções sempre serão adicionadas ao final do arquivo de dados. Em seguida, as seleções e inserções podem ocorrer simultaneamente, mas seu arquivo de dados nunca ficará menor, não importa quantos registros você exclua (exceto todos os registros).
A linha inferior, se você tem muitas atualizações, insere e seleciona em uma tabela, deve fazê-lo no InnoDB. Você pode combinar livremente tipos de tabela em um sistema.
fonte
Outra maneira de habilitar a leitura suja no mysql é adicionar uma dica: LOCK NO SHARE MODE
fonte
A partir desta referência:
fonte
Os SELECTs normalmente não fazem nenhum bloqueio de seu interesse nas tabelas do InnoDB. O nível de isolamento da transação padrão significa que as seleções não bloqueiam coisas.
Claro que a disputa ainda acontece.
fonte
show processlist
para realmente ver os bloqueios. Portanto, é seguro supor que, de fato, existem bloqueios sendo feitos.