Subquery

我的子查詢是否無效。它非常慢

  • August 20, 2014

我有兩張桌子。會員資訊和登錄條目。我只是想顯示按上次登錄訪問日期排序的成員資訊表。所以我創建了這個查詢,但它非常慢。有沒有更好的寫法?

SELECT
   menmembers.memb_id, 
   menmembers.firstname, 
   menmembers.lastname, 
   (SELECT Max(trank.datetr) AS MaxOfdatetr
       FROM trank 
       where trank.cod_usr=menmembers.memb_id;) AS LastLogin
FROM menmembers;

由於子選擇,您的查詢很慢。這就是所謂的相關子查詢。它將在外部查詢中每行執行一次。

這個問題回答了一個類似的問題。它在尋找最小值,你在尋找最大值;它正在使用一張桌子,您正在使用一張桌子。不過翻譯應該不會太難。

有兩種方法(不相互排斥)可以提高查詢性能。首先,您可以將相關子查詢重寫為具有聚合的子查詢:

SELECT
   m.memb_id, 
   m.firstname, 
   m.lastname, 
   t.LastLogin
FROM menmembers AS m
LEFT JOIN (
   SELECT cod_usr, MAX(datetr) AS LastLogin
   FROM trank
   GROUP BY cod_usr
   ) AS t ON m.memb_id=t.cod_usr;

其次,您可以將適當的索引添加到trank

CREATE /* UNIQUE? */ INDEX IX_trank_LastLogin ON trank (cod_usr, datetr);

僅僅為了查詢性能,我會考慮在這個索引中對 datetr 列 DESC 進行排序,儘管這對於 INSERT 到表中可能不是最佳的。或者,您可以只包含 datetr 列:

CREATE INDEX IX_trank_LastLogin ON trank (cod_usr) INCLUDE (datetr);

顯然,您也應該有一個索引menmembers.memb_id才能正常工作,但我猜這已經處理好了。

我已經為 SQL Server 編寫了這段程式碼,但是由於您沒有標記您的 dbms,我不能確定它是否適用於您的設置。

引用自:https://dba.stackexchange.com/questions/74397