簡體   English   中英

多個表上帶有WHERE子句的SQL JOIN速度降低

[英]SQL JOIN with WHERE clause on multiple tables slowdown

以下查詢速度很快:

SELECT a.id, b.id, c.id
FROM a
FULL OUTER JOIN b ON a.id = b.id
FULL OUTER JOIN c ON a.id = c.id
WHERE a.some > 5 AND a.thing < 10

但是在多個表上執行where子句會導致我的數據集中的性能損失大約1000萬X:

SELECT a.id, b.id, c.id
FROM a
FULL OUTER JOIN b ON a.id = b.id
FULL OUTER JOIN c ON a.id = c.id
WHERE (a.some > 5 AND a.thing < 10)
    OR (b.some > 5 AND b.thing < 10)
    OR (c.some > 5 AND c.thing < 10)

如何提高查詢的性能? 謝謝!

編輯:

這是關於實際查詢的sql解釋(表名稱有些不同):

SELECT
    ohh.hour
FROM org_hour_host ohh
FULL OUTER JOIN org_hour_timeseries ohs ON ohh.org_id = ohs.org_id
FULL OUTER JOIN org_hour_vs_host ohah ON ohh.org_id = ohah.org_id
WHERE (ohh.org_id IN (10) OR ohs.org_id IN (10) OR ohah.org_id IN (10))

XN Hash Full Join DS_DIST_OUTER  (cost=6682944.40..234919986923528960.00 rows=1934276754413 width=8)
  Outer Dist Key: "outer".org_id
  Hash Cond: ("outer".org_id = "inner".org_id)
  Filter: (("inner".org_id = 10) OR ("outer".org_id = 10) OR ("outer".org_id = 10))
  ->  XN Hash Full Join DS_DIST_NONE  (cost=3050316.80..38694799792.93 rows=1934276754413 width=16)
        Hash Cond: ("outer".org_id = "inner".org_id)
        ->  XN Seq Scan on org_hour_host ohh  (cost=0.00..3130270.08 rows=313027008 width=12)
        ->  XN Hash  (cost=2440253.44..2440253.44 rows=244025344 width=4)
              ->  XN Seq Scan on org_hour_timeseries ohs  (cost=0.00..2440253.44 rows=244025344 width=4)
  ->  XN Hash  (cost=2906102.08..2906102.08 rows=290610208 width=4)
        ->  XN Seq Scan on org_hour_vs_host ohah  (cost=0.00..2906102.08 rows=290610208 width=4)
(11 rows)





SELECT
    ohh.hour
FROM org_hour_host ohh
FULL OUTER JOIN org_hour_timeseries ohs ON ohh.org_id = ohs.org_id
FULL OUTER JOIN org_hour_vs_host ohah ON ohh.org_id = ohah.org_id
WHERE ohh.org_id IN (10)

XN Merge Left Join DS_DIST_NONE  (cost=0.00..6350089909.81 rows=634262751009 width=8)
  Merge Cond: ("outer".org_id = "inner".org_id)
  ->  XN Merge Left Join DS_DIST_NONE  (cost=0.00..3667829.03 rows=64777233 width=12)
        Merge Cond: ("outer".org_id = "inner".org_id)
        ->  XN Seq Scan on org_hour_host ohh  (cost=0.00..131.03 rows=10483 width=12)
              Filter: (org_id = 10)
        ->  XN Seq Scan on org_hour_timeseries ohs  (cost=0.00..2440253.44 rows=244025344 width=4)
  ->  XN Seq Scan on org_hour_vs_host ohah  (cost=0.00..2906102.08 rows=290610208 width=4)
(8 rows)

在第一個查詢中,子句a.some > 5 AND a.thing < 10排除了a.somea.thing為NULL的行。 這使聯接成為LEFT聯接。 在第二個查詢中,如果b.some > 5 AND b.thing < 10為true b.some > 5 AND b.thing < 10a.somea.thing可以為NULL。 因此,現在的FULL JOIN是實際的FULL JOIN,它們提供了更多的行。 最后,WHERE子句中的OR相對較慢。

從理論上講,您可以在加入之前先應用條件,這樣可以減少要過濾的行和要加入的行。 未經測試,但這看起來像:

SELECT a.id, b.id, c.id
FROM (SELECT * FROM tbl_a 
      WHERE some > 5 AND thing < 10) a
FULL OUTER JOIN (SELECT * FROM tbl_b 
      WHERE some > 5 AND thing < 10) b ON a.id = b.id
FULL OUTER JOIN (SELECT * FROM tbl_c 
      WHERE some > 5 AND thing < 10) c ON a.id = c.id

暫無
暫無

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

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