非常に大規模な EAV またはオープン スキーマ スタイルのデータベースを SQL Server に実装した人はいますか? これにパフォーマンス上の問題があるかどうか、そしてそれらの障害をどのように克服できたのか疑問に思っています.
2 に答える
MS SQL Server と他のブランドのデータベースに関係なく、EAV の最悪のパフォーマンスの問題は、単一の行でエンティティを再構築するためにモンスター クエリを実行しようとすることです。 これには、属性ごとに個別の結合が必要です。
SELECT e.id, a1.attr_value as "cost", a2.attr_value as "color",
a3.attr_value as "size", . . .
FROM entity e
LEFT OUTER JOIN attrib a1 ON (e.entity_id = a1.entity_id AND a1.attr_name = 'cost')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a2.entity_id AND a2.attr_name = 'color')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a3.entity_id AND a3.attr_name = 'size')
. . . additional joins for each attribute . . .
使用するデータベース ブランドに関係なく、クエリ内の結合が増えると、パフォーマンス コストが幾何学的に増加します。必然的に、SQL エンジンのアーキテクチャ容量を超える十分な属性が必要になります。
解決策は、属性を列ではなく行でフェッチし、アプリケーション コードでクラスを記述してこれらの行をループし、値をオブジェクト プロパティに 1 つずつ割り当てることです。
SELECT e.id, a.attr_name, a.attr_value
FROM entity e JOIN attrib a USING (entity_id)
ORDER BY e.id;
この SQL クエリは非常に単純で効率的であるため、追加のアプリケーション コードを補うことができます。
私が EAV フレームワークで探しているのは、このような複数行の結果セットを取得し、属性をオブジェクト プロパティにマップしてから、入力されたオブジェクトのコレクションを返すボイラープレート コードです。
私は EAV の専門家ではありませんが、Magento のオープンソースの電子商取引フレームワークは、主に MySQL による EAV アーキテクチャが原因で遅いとコメントしている経験豊富な開発者が何人かいます。最も明らかな欠点は、簡単には克服できません。これは、アプリケーションのサイズが大きくなるにつれて、エンティティと属性値の情報がどこでどのように表現されるかをトラブルシューティングすることの難しさです。私が聞いた EAV に対する 2 番目の議論は、2 桁台前半になるテーブル結合が必要だというものですが、MyISAM で InnoDB を使用するとパフォーマンスがいくらか向上したとコメントされていました (またはその逆の可能性もありますが、完全には思い出せません)。 )。