簡體   English   中英

如何更好地編寫此Mysql Join查詢

[英]How to write better this Mysql Join query

我有下一張桌子

Users {id, name}
Messages {id, user_id, cache_user_name}

我想要的是僅出於性能原因在cache_user_nameNULL時執行JOIN。

例如:

SELECT Messages.*, Users.name FROM Messages INNER JOIN Users ON (Messages.user_id = Users.id) 
// ON (ISNULL(Messages.cache_user_name) AND ...

最好的方法是執行2個查詢? 1用於沒有緩存(聯接)的行,另一用於具有聯接的緩存行?

[編輯]

我需要的結果是:

用戶數

ID: 1, NAME: Wiliam

留言內容

ID: 1, USER_ID: 1, CACHE_USER_NAME: Wiliam
ID: 2, USER_ID: 1, CACHE_USER_NAME: null

結果

ID: 1,  USER_ID: 1,  CACHE_USER_NAME: Wiliam,  USERS.NAME: null   // No join, faster
ID: 2,  USER_ID: 1,  CACHE_USER_NAME: null,    USERS.NAME: Wiliam // Join

您可以添加WHERE ... IS NULL子句。

優化器將(嘗試)使用性能最佳的計划。

SELECT   Messages.*
         , Users.name 
FROM     Messages 
         INNER JOIN Users ON (Messages.user_id = User.id)
WHERE    Users.cache_user_name IS NULL

編輯

給定以下數據,您期望輸出什么?

DECLARE @Users TABLE (ID INTEGER, Name VARCHAR(32))
DECLARE @Messages TABLE (ID INTEGER, User_ID INTEGER, Cache_User_Name VARCHAR(32))

INSERT INTO @Users VALUES (1, 'Wiliam')
INSERT INTO @Users VALUES (2, 'Lieven')
INSERT INTO @Users VALUES (3, 'Alexander')

INSERT INTO @Messages VALUES (1, 1, NULL)
INSERT INTO @Messages VALUES (2, 1, 'Cached Wiliam')
INSERT INTO @Messages VALUES (3, 2, NULL)
INSERT INTO @Messages VALUES (4, 3, 'Cached Alexander')

SELECT  *
FROM    @Users u
        INNER JOIN @Messages m ON m.User_ID = u.ID
WHERE   m.Cache_User_name IS NULL        
SELECT m.Id, m.user_id, CACHE_USER_NAME user_name
FROM messages m
WHERE CACHE_USER_NAME IS NOT NULL
UNION ALL
SELECT m.Id, m.user_id, u.user_name user_name
FROM (Select * from messages Where cache_user_name IS NULL) m
JOIN users ON (u.user_id = m.user_id)

無論如何,最好的方法是在創建消息期間將cache_user_name存儲在表消息中。 然后,您將完全需要加入。

我認為這些與以前的答案一起使用Not Null where子句應該可以正常工作,但也許我們沒有關注您的效率低下問題。 只要對users.id和messages.user_id進行了索引並且具有相同的類型,那么除非您擁有龐大的用戶數據庫和大量消息,否則該聯接不會很慢。 如果有的話,扔更多的硬件; 可能您正在運行大量流量並負擔得起。 :)

另外,您也可以這樣處理:對名稱不為null的消息進行查詢,遍歷結果,查找每條消息的名稱(並將它們放入數組中),然后在用戶表中查詢那些名稱名稱。 然后,當您遍歷“消息”結果時,可以顯示您保存的陣列中的正確名稱。 您將有兩個查詢,但是它們很快。

$users = $messages = $users_ids = array ();

$r = mysql_query('select * from Messages where cache_user_name is not null');
while ( $rs = mysql_fetch_array($r, MYSQL_ASSOC) )
{
    $user_ids[]    = $rs['user_id'];
    $messages[] = $rs;
}

$user_ids = implode ( ',', $user_ids );
$u = mysql_query("select * from Users where id in ($users)");

while ( $rs = mysql_fetch_array($r, MYSQL_ASSOC) )
{
    $users[$rs['id']] = $rs['name'];
}


foreach ( $messages as $message )
{
    echo "message {$message['id']} authored by " . $users[$message['user_id']] . "<br />\n";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM