首頁>Database>source
情况

我们在RDS上託管了一个資料庫,其中包含數百个表,其中一些表非常大。

我们最近將資料庫从9.5.22升級到11.8,並且效能明顯下降。

升級後,我们執行了 VACUUM ANALYZE 在例項上(相對於 ./analyze_new_cluster.sh 因為我们無法在RDS例項上執行Shell。

這對情况没有帮助.我啟動了另一个資料庫的独立11.8例項,並執行了 VACUUM FULL ANALYZE ,並且该資料庫表現出相同的查詢計划者行為,因此包括 FULLVACUUM 命令没有帮助(如某些SO答案所建議)。

我们找到了一个查詢,该查詢顯示了升級前後效能的最大變化:

SELECT f.uuid, p.name FROM flights f LEFT OUTER JOIN passengers p     ON f.uuid = p.flight_id WHERE f.uuid IN (< UUIDs >) ORDER BY f.date_created ASC;
最新回復
  • 5月前
    1 #

    您的統計資訊在各个版本之間變化不大.它们在两者上都相差很大.但是改變的是,由於存在並行計划,糟糕的統計資料使並行計划看起来很有吸引力。

    This is actually because the UUIDs I provide to the query did not exist in the flights table. I merely wanted to pass in a larger number to trigger the different behavior on how to scan the flights table.

    在高基數的列中查詢碰巧不存在的值本質上很难正確估計.你為什麼做這个? 在這裏听起来像您正在故意建立問题,但是听起来好像您是在發生此問题,因為它是自然發生的.两者怎麼都成立? 也许您人為製造的這个問题与您遇到的自然問题没有相同的根本原因(或相同的解決方案)。

    I experimented by setting max_parallel_workers_per_gather = 0, which also had the desired effect of coercing the postgres 11 to return a query plan that avoided the sequential scan, but I do not think it is wise to disable that functionality for the database.

    將其設置為關闭的原因似乎很清楚(假設您的一个示例代表了實際問题),而您不想關闭它的原因似乎很模糊.您是否专門进行了升級以訪問並行查詢?

    So before someone suggests to increase that value, why would that help the postgres 11 instance if the postgres 9.5 instance produces a "good" plan without them?

    如果您没有太多選擇,很容易意外地做出正確的決定.開放並行化提供了更多的解決方法,而糟糕的統計資料使得很可能会選擇這些不好的方法之一.话虽如此,提高統計目標無論如何都無济於事,除非您可以增加到超過1,700万,這是您無能為力的(即使那樣我也认為那無济於事)。

    Is there something about postgres 11 (parallel workers?) that makes it think it can perform the sequential scan faster than the index scan? This seems unlikely given that the planner expects to return 21 rows but at a huge cost

    它认為从並行查詢中受益的不仅是seq掃描.通過並行執行航班的seq掃描,它认為對乘客的索引掃描也將固有地並行執行,因此它认為大部分假定收益將来自此.尽管這不是一个完整的解釋,例如通過關闭enable_seqscan,我仍然希望使用並行計划,仅對飞行进行並行索引掃描或並行位圖堆掃描.我無法解釋為什麼仅由於enable_seqscan = off会完全放棄並行.而且我無法在v11中用模擬資料重現该行為。

  • 5月前
    2 #

    我有類似的問题.当我使用CTE時,問题就消失了。

    with my_uids as (
    select distinct unnest(array['a','b','c','d']) uid order by 1
    --a,b,c,d <--- yours uuids
    )
    SELECT f.uuid, p.name
    FROM flights f 
    join my_uids mu on (mu.uid = f.uuid)
    LEFT OUTER JOIN passengers p 
        ON f.uuid = p.flight_id 
    ORDER BY f.date_created ASC;
    

  • windows:無法重設MySQL密碼
  • sql server:如何从值相互包含的两个表中排除行?