Почему учение использует ГДЕ ВНУТРИ вместо ОГРАНИЧЕНИЯ? - PullRequest
6 голосов
/ 10 января 2011

Почему доктрина (1.2) использует WHERE IN вместо LIMIT?

Этот код:

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

Возвращает что-то вроде этого:

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);

Вместо этого:

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

Это поведение одинаково для любого значения LIMIT.Это приводит к очень длинным запросам для высоких значений LIMIT.

Бонусный вопрос: как Doctrine узнает, какие идентификаторы использовать?(Отправив еще один запрос в БД ??)

Ответы [ 2 ]

4 голосов
/ 10 января 2011

Это потому, что LIMIT работает со строками базы данных, а не с "объектами".Когда вы набираете $q->limit(10), вы хотите получить десять объектов, а не десять строк из базы данных.

Рассмотрите следующий запрос (продукты и категории имеют отношение «многие ко многим»):

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;

Чтобы получить 10 товаров (объектов), ваш запрос должен получить не менее 20 строк.Вы не можете использовать LIMIT 10, потому что (только для примера) будут возвращены только 3 продукта.Вот почему вам необходимо выяснить, какие продукты следует выбрать (ограничение относится к продуктам), а затем извлечь фактические данные.

Это приведет к следующим запросам:

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

Второй запросможет вернуть 20, 423 или 31 строку.Как видите, это не значение из limit().

PS.В этом случае Doctrine2 гораздо понятнее, так как использует setMaxResults() метод вместо limit(), что не так сложно.

0 голосов
/ 10 января 2011

Использование Doctrine 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;

Я получаю результат:

SELECT t.id_table AS t__id_table FROM table t LIMIT 10

Может быть, что-то еще происходит в вашем коде?

...