我正在開發一個權限驗證系統。為了驗證用戶是否可以訪問檔案,我向資料庫發出請求 有兩種情況可以訪問:
- 用戶位于此檔案的訪問區域(例如,發布檔案的聊天中的用戶)
select count(*) > 0 from Document
left join Chat
left join ChatUser
left join User
left join Resource
...
where ...
- 檔案是公開的
select count(*) > 0 from Document
left join User
left join Resource
left join ...
...
where ...
我看到了 2 個解決方案
- 提出涵蓋兩種情況的請求(聯合)
這種解決方案的優點-> 對資料庫的 1 個請求
這種解決方案的缺點 -> 每次在 70% 的情況下,我都會額外進行 5 次連接,這會影響資料庫中查詢的性能
- 提出 2 個請求
首先請求檔案是否在聊天中。
如果為 false -> 則再發出 1 個請求
告訴我在這種情況下使用什么演算法?
uj5u.com熱心網友回復:
如果您有一對一的關系,則應使用聯接查詢。
具有一對多關系的聯接查詢將導致更多的記憶體使用與冗余資料。
如果您沒有記憶體使用問題,那么您也應該使用連接查詢,因為在大多數情況下,連接查詢比多個查詢更快。
uj5u.com熱心網友回復:
如果您認為網路延遲會破壞交易,為什么不在 plsql 函式中卸載“如果一開始沒有找到,請嘗試第二個查詢”?您只需要查詢該函式一次,它將回傳一個布林值。哎呀,如果您的應用需要該資訊,您可以輕松添加另一個標志,指示它是在聊天中找到它還是需要查看公共標志。
也就是說,您可能可以通過重寫查詢來獲得相當多的性能
select count(*) > 0 from Document
left join Chat
left join ChatUser
left join User
left join Resource
...
where ...
至
SELECT (CASE WHEN EXISTS (
select * from Document
left join Chat
left join ChatUser
left join User
left join Resource
...
where ... ) THEN True ELSE False END)
這樣,系統不需要檢查所有適用的情況,但可以在第一場比賽時停止。
我也覺得奇怪的是你LEFT OUTER JOIN在那里有 s 而不是INNER JOINs 但這可能是把它放在 StackOverflow 上的簡化,對吧?
我實際上想知道是否僅使用合并兩個查詢WHERE EXISTS()不會使優化器執行“只有在第一次未找到時才執行第二部分”......EXPLAIN ANALYZE應該很清楚。使用https://explain.dalibo.com/或類似的東西使其更易于解釋。
所以,它會變成這樣:
SELECT (CASE WHEN EXISTS (
select * from Document
join Chat
join ChatUser
join User
join Resource
...
where ... )
OR EXISTS (
select * from Document
join User
join Resource
join ...
...
where ... )
THEN True ELSE False END)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/514709.html
上一篇:自我加入究竟是如何作業的?
