2011-01-10 13 views
6

¿Por qué la doctrina (1.2) usa WHERE IN en lugar de LIMIT?¿Por qué la doctrina usa DONDE EN lugar de LÍMITE?

este código:

Doctrine_Query::create() 
    ->from('Table t') 
    ->limit(10) 
    ->getSqlQuery(); 

devoluciones algo como esto:

SELECT t.id_table AS t__id_table FROM table AS t WHERE t__id_table IN (1,2,3,4,10,12,18,20,21,25); 

lugar de esto:

SELECT t.id_table AS t__id_table FROM table AS t LIMIT 10; 

Este behaivor es igual para cualquier valor LIMIT. Esto genera consultas muy largas para valores altos de LIMIT.

Pregunta de bonificación: ¿Cómo sabe Doctrine, qué identificadores usar? (¿Al enviar otra consulta a DB?)

+0

¿Qué back-end de base de datos está utilizando? –

+0

@Matt Gibson: MySQL –

+0

Impar; Acabo de hacer algo similar con Doctrine de Symfony 1.4, que creo que es la versión 1.2.3, y usa la cláusula LIMIT para MySQL, como era de esperar. –

Respuesta

4

Esto se debe a que LIMIT opera en las filas de la base de datos no en "objetos". Cuando escribe $q->limit(10), desea obtener diez objetos, no diez filas de la base de datos.

Considere siguiente consulta (productos y categorías tienen muchos-a-muchos relación):

SELECT p.*, c.* FROM product p 
INNER JOIN product_category_ref pcr ON p.id = pcr.prodcut_id 
INNER JOIN category c ON c.id = pcr.category_id 
WHERE p.price < 123; 

recoger 10 productos (objetos) la consulta tendrá a buscar al menos 20 filas. No puede usar LIMIT 10 porque (solo por ejemplo) solo se devolverán 3 productos. Es por eso que debe averiguar qué productos deben buscarse (el límite se aplica a los productos) y luego buscar los datos reales.

que dará lugar a consultas siguientes:

SELECT p.id FROM product p WHERE p.price < 123; 
SELECT ..... WHERE p.id IN (...); 

Segunda consulta puede devolver 20, 423 o 31 filas. Como puede ver, ese no es un valor de limit().

PS. Doctrine2 es mucho más claro en ese caso, ya que está utilizando el método setMaxResults() en lugar de limit(), lo que es menos confuso.

+0

de dónde obtienes esta información? de acuerdo con el límite manual() es parte de DQL y se usa antes de la hidratación –

+0

Lo sé por mi propia experiencia y estudio de las fuentes. Y sí, tienes razón: 'LIMIT' es parte de DQL (el método' limit() 'proviene de' QueryBuilder') y como puedes ver, se usa antes de la hidratación (la segunda consulta (la que está realmente hidratada) doesn incluso tiene la cláusula 'LIMIT')). – Crozin

+0

Esto me suena extraño. Yo (y mis colegas) pensamos que el LIMIT se aplica al número de filas que devuelve la consulta (después de procesar todas las uniones, subconsultas, etc.). –

0

Usando Doctrina 1.2.3:

<?php 

include(dirname(__FILE__).'/Doctrine.php'); 
spl_autoload_register(array('Doctrine', 'autoload')); 

$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'testdb', 'testdb'); 
$conn = Doctrine_Manager::connection($dbh); 

class Table extends Doctrine_Record { 
    public function setTableDefinition() { 
    $this->hasColumn('id_table', integer, 10, array('primary' => true)); 
    } 
} 

$q = Doctrine_Query::create() 
    ->from('Table t') 
    ->limit(10) 
    ->getSqlQuery(); 

echo $q; 

puedo obtener el resultado:

SELECT t.id_table AS t__id_table FROM table t LIMIT 10 

¿Hay tal vez algo más en juego en el código?

+0

Acabamos de enterarnos de que DONDE IN se usa solo cuando se usa JOIN. Perdón por confundir. –

Cuestiones relacionadas