許多列與少數表 - 性能方面
是的,我知道數據規範化應該是我的首要任務(事實上)。
- 我有一個包含 65 列的表,用於儲存車輛數據,列:
used_vehicle
、color
、doors
、等等,總共 65 個mileage
。price
- 現在,我可以把它分開並有一個
Vehicle
表,VehicleInterior
,VehicleExterior
,VehicleTechnical
,VehicleExtra
(與主表都是一對一的Vehicle
)。假設我將有大約 500 萬行(車輛)。
On
SELECT
with aWHERE
子句:搜尋性能是否會更好(兩種情況都至少索引 onIDs
):
Vehicle
有 65 列的表格或Vehicle
與JOINS
其他四個表(全部有 500 萬行)的表返回與Vehicle
?相關的所有數據(根據數據庫引擎,考慮 PostgreSQL 和/或 MySQL)。
真的很欣賞您從以前的經驗中可能獲得的任何詳細見解嗎?
如果有的話,更新將很少,並且選擇主要針對搜尋結果列表的所有列(車輛詳細資訊頁面)和主要資訊(少數列),事實上,最好的解決方案可能是兩個表:一個包含主要資訊(很少列)和另一個包含其餘列的表。
假設我們正在討論所有表之間的 1:1 關係。
使用單個表而不是 1:1 關係中的多個表,總體儲存實際上*總是(基本上)便宜。*每行有 28 個字節的成本,通常還有幾個字節用於額外的填充。並且您需要將 PK 列與每個表一起儲存。並且在這些列中的每一個上都有一個單獨的(冗餘)索引……大小確實對性能很重要。
如果大多數行中的許多列都為 NULL,這甚至是正確的,因為NULL 儲存非常便宜:
在檢索所有列時,單個表比連接在一起的 5 個表要快得多。它也簡單得多。如果不是所有表中都存在所有行,則連接五個表可能會很棘手。使用
WHERE
針對單個表的條件,很容易將其他表附加到LEFT JOIN
. 如果您在多個表上都有謂詞,那就不是那麼簡單了……垂直分區 仍然可以提高某些查詢的性能。例如,如果 90% 的查詢從 65 個可用列中檢索到相同的 5 個列,那麼使用僅包含這 5 個列的表會更快。
- 查詢期間從磁碟檢索什麼?(我的答案)
OTOH,您也許可以使用允許僅索引掃描的“覆蓋”索引來滿足對幾個選定列的此類查詢。
垂直分區的另一個候選者:如果您只對幾列進行**大量更新,而其餘的幾乎不會改變。**在這種情況下拆分行可能會便宜得多,因為 Postgres 會為每次更新寫入一個新的行版本。離線儲存的大值(“TOASTed”)有例外。更多細節:
- 查詢期間從磁碟檢索什麼?(丹尼爾的回答)
- 更新另一個表中的所有列
這真的取決於完整的情況。如果有疑問,請使用單張桌子的簡單解決方案,特別是如果它很好地描繪了現實:在您的範例中,這些都是汽車的所有屬性並且一起有意義。