2016-07-03 77 views
0

請看看這兩個查詢:VS外部查詢

一:

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,所以你應該理解它。

第二個是MySQL中having子句的擴展。通常,having子句只能用於聚合查詢 - 您會在查詢中看到聚合函數。在MySQL(和其他幾個數據庫)中,having允許使用列別名,而WHERE子句不允許。

讓我們添加一個更重要的考慮事項。一般來說,MySQL 實現了子查詢。這意味着子查詢會產生額外的開銷來寫出數據並將其讀回。大多數其他數據庫具有更好的優化器,並且不會實現FROM子句中的所有/大部分子查詢。

因此,爲了提高效率,MySQL允許您在非聚合查詢中使用HAVING子句。在這種情況下,它的功能就像WHERE子句,除了可以引用列別名。

結論:第一個更好,因爲它是更標準的SQL。第二個更好,因爲它應該運行得更快。一切都取決於你的意思是「更好」。