2016-07-03 3 views
0

Пожалуйста, обратите внимание на эти два запроса:имеющий VS внешний запрос

One:

INSERT INTO QandA (id, body, type, related, author_id, date_time) 
    SELECT NULL, :body, 0, NULL, :id, unix_timestamp 
    FROM (select count(*) as num_month, 
       count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day))) as num_day, 
       count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 90 minute))) as num_90min 
      from QANDA 
      where author_id = :id and 
       type = 0 and 
       date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 50 day)) 
     ) a 
    WHERE num_month < 50 and num_day < 6 and num_90min < 1; 

Два:

INSERT INTO QandA (id, body, type, related, author_id, date_time) 
SELECT NULL, :body, 0, NULL, :id, unix_timestamp 
FROM dual 
WHERE user_id = :id 
    AND NOT EXISTS (
     SELECT count(*) AS num_month 
       count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day))) as num_day, 
       count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 90 minute))) as num_90min 
     FROM QandA 
     WHERE author_id = :id and 
       type = 0 and 
       date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 50 day)) 
     HAVING num_90min > 50 
      OR num_day > 6 
      OR num_month > 1 
    ) 

Как вы видите, оба areidentical, только первый использует внешний запрос , а второй использует having статья. Ну какой подход лучше? Или есть какой-то третий подход, который является блефом, чем их?

ответ

0

Первый стандарт SQL, поэтому вы должны это понимать.

Второй является расширением предложения having в MySQL. Обычно предложение having будет использоваться только в запросе агрегации - вы увидите функции агрегации где-нибудь в запросе. В MySQL (и нескольких других базах данных) having позволяет использовать псевдонимы столбцов, тогда как в предложении WHERE нет.

Давайте добавим еще одно важное соображение. В общем, MySQL материализует подзапросы. Это означает, что подзапрос будет нести дополнительные накладные расходы, чтобы выписать данные и прочитать их обратно. Большинство других баз данных имеют лучшие оптимизаторы и не материализуют все/большинство подзапросов в предложении FROM.

Таким образом, чтобы быть более эффективным, MySQL позволяет использовать предложение HAVING в запросе без агрегации. В этом случае он функционирует так же, как предложение WHERE, за исключением того, что вы можете ссылаться на псевдонимы столбцов.

Заключение: первое лучше, потому что это более стандартный SQL. Второй лучше, потому что он должен работать быстрее. Все зависит от того, что вы подразумеваете под «лучше».

Смежные вопросы