我正在重寫SQL,它允許用戶搜索我們網站上的任何其他用戶並顯示他們的角色。MySQL搜索用戶及其角色
舉個例子,角色可以是「Writer」,「Editor」,「Publisher」。
每個角色都將用戶鏈接到發佈。
用戶可以在多個出版物中擔任多個角色。
例表設置:
"users" : user_id, firstname, lastname
"publications" : publication_id, name
"link_writers" : user_id, publication_id
"link_editors" : user_id, publication_id
當前僞SQL:
SELECT * FROM (
(SELECT user_id FROM users WHERE firstname LIKE '%Jenkz%')
UNION
(SELECT user_id FROM users WHERE lastname LIKE '%Jenkz%')
) AS dt
JOIN (ROLES STATEMENT) AS roles ON roles.user_id = dt.user_id
此刻我的角色的說法是:
SELECT dt2.user_id, dt2.publication_id, dt.role FROM (
(SELECT 'writer' AS role, link_writers.user_id, link_writers.publication_id
FROM link_writers)
UNION
(SELECT 'editor' AS role, link_editors.user_id, link_editors.publication_id
FROM link_editors)
) AS dt2
原因包裹在UNION角色聲明子句是有些角色更加複雜,需要通過表連接才能找到publication_id和user_id。
舉個例子「出版商」可能翻過兩個表
"link_publishers": user_id, publisher_group_id
"link_publisher_groups": publisher_group_id, publication_id
因此,在這種情況下鏈接,查詢我的形成聯盟的一部分將是:
SELECT 'publisher' AS role, link_publishers.user_id, link_publisher_groups.publication_id
FROM link_publishers
JOIN link_publisher_groups ON lpg.group_id = lp.group_id
我很有信心我的表格設置是好的(在研究佈局時,我被警告不要使用一個表格)。我的問題是用戶表中現在有100,000行,每個鏈接表中最多有70,000行。
用戶表中的初始查詢速度很快,但加入會降低速度。
我該如何才能加入相關角色?
--------------------------編輯------------------- --------------- explain http://img155.imageshack.us/img155/4758/stackusersearchjoins.gif
上面解釋(在新窗口中打開以查看完整分辨率)。
紅色底部是「WHERE firstname LIKE'%Jenkz%'」第三行搜索WHERE CONCAT(firstname,'',lastname)LIKE'%Jenkz%'。因此,大行數,但我認爲這是不可避免的,除非有一種方法可以將一個索引放在串聯字段中?
頂部的綠色位僅顯示從角色狀態報告中掃描的總行數。
然後,您可以看到每個單獨的UNION子句(#6 - #12),它們都顯示大量的行。一些指標是正常的,有些是獨特的。
似乎MySQL並未優化使用dt.user_id作爲UNION語句內部的比較。有什麼辦法來強制這種行爲?
請注意,我真正的設置不是出版物和作家,而是「網站管理員」,「玩家」,「團隊」等。
它看起來像UNION中的select語句應該被限制爲「WHERE user_id = dt.user_id」。 – Martin 2010-03-17 13:26:28
感謝您的評論馬丁。不幸的是,我無法訪問我的UNION子句中的「dt」數據。試着給出錯誤「未知列dt.user_id」。 – 2010-03-17 13:52:09
我不認爲這樣的SQL有任何問題 - 我期望dt和dt2之間的user_id上的join操作將執行限制Jenkz談話。除非工會以某種方式打破了普通的優化器。你確定表格有正確的索引嗎?你可以發佈這個查詢的解釋輸出嗎? – AHM 2010-03-17 17:43:38