Dado que o db_select é muito mais lento que o db_query, por que eu iria querer usá-lo?

69

Para obter mais informações, consulte http://drupal.org/node/1067802 .

Dado tudo isso, que situações existem em que eu gostaria de usar o db_select () ou devo confiar apenas no db_query?

Chris Cohen
fonte

Respostas:

88

Existem 5 razões para usar o SelectQuery

  • Você está criando consultas dinâmicas com um número variável de condições, junções, campos e assim por diante. Veja field_read_fields () para um exemplo.

  • Você deseja usar os chamados Extensores . Os extensores de exemplo são PagerDefault (substitui pager_query () ) e TableSort (substitui tablesort_sql () ). Isso permite adicionar funcionalidade adicional ao SelectQuery. Consulte também Como você cria tabelas classificáveis ​​com um pager com dados de uma tabela personalizada? . Um exemplo: node_page_default () .

  • Você deseja permitir que outros módulos alterem suas consultas. Em seguida, você pode adicionar as chamadas tags e o SelectQuery chamará automaticamente um alter hook correspondente para essa tag. Estou confiando bastante nisso com meu módulo Privatemsg (já fizemos isso no D6 com um construtor de consultas personalizado).

  • Se você deseja / precisa usar o sistema node_access para mostrar apenas os nós que o usuário tem permissão para ver. Basta adicionar a tag 'node_access' à sua consulta $. Isso substitui db_rewrite_sql ().

  • O SelectQuery possui alguns recursos que ajudam a fazer com que seu código funcione da mesma forma em todos os bancos de dados suportados. Por exemplo, há SelectQuery :: orderRandom () . E se você tiver uma condição LIKE, -> condition ('field', $ value, 'LIKE') garantirá que seja sempre uma comparação que não diferencia maiúsculas de minúsculas. No D6, você tinha que usar LOWER () para o que era muito mais lento. Mas AFAIK, não há mais do que esses dois agora.

Se nenhum desses motivos se aplicar a um caso específico, use db_query ().

Berdir
fonte
11
Adicionado um quinto ponto, os recursos de portabilidade do banco de dados, como orderRandom () e LIKE que não diferenciam maiúsculas de minúsculas.
Berdir 23/03
6
Como sexto motivo, eu adicionaria compatibilidade entre bancos de dados. As consultas Oracle, por exemplo, têm uma sintaxe que difere de alguma forma do MySQL, Postgres etc. É muito mais fácil escrever código para gerar a sintaxe correta a partir de um db_select () do que quando um código de consulta não muito compatível com oracle é despejado diretamente em db_query ().
BrianV
9

A documentação sobredb_query() diz:

Use esta função para consultas SELECT se for apenas uma sequência de consultas simples. Se o chamador ou outros módulos precisarem alterar a consulta, use db_select ().

Marcvangend
fonte
Obrigado, mas isso é bastante inespecífico. Deixa a definição de 'string de consulta simples' bastante aberta à interpretação. Se eu estiver selecionando 4 tabelas com 6 junções, isso ainda é uma consulta simples ou deve ser feita com db_select ()?
Chris Cohen
3
Não se trata de "consulta simples", mas de uma " sequência de consultas simples " e simples, na verdade, significa codificado e não dinâmico. Veja a minha resposta para mais detalhes :)
Berdir
9

Eu sempre uso o db_select porque prefiro legibilidade, capacidade de manutenção e compatibilidade entre bancos de dados em vez de pequenos ganhos de desempenho. Além disso, acho que os números apresentados na edição mencionada dão uma imagem errada do desempenho geral. Estamos falando de uma diferença de 300 microssegundos em uma consulta que, ao retornar mais de uma única coluna, geralmente é executada no intervalo de vários milissegundos. E não ficaria surpreso se houver apenas uma sobrecarga única (carregamento de classe) e, portanto, que as diferenças para uma solicitação completa (de página) sejam muito menores.

fietserwin
fonte
A diferença de desempenho não é tão simples; consulte Compare o desempenho de db_query e db_select . Eu geralmente recomendo o db_query sobre o db_select, a menos que você precise de um dos recursos especiais mencionados na resposta de Berdir.
geerlingguy