0

私はすべて、同じレイアウトの2つの同様の非常に大きなテーブル(それぞれ1M行)を持っています。それらを結合し、共通の列でソートします: start 。また、「start」に条件を入れます。つまり、start>X です。問題は、ビューが開始のインデックスを気にせず、複雑さが大幅に上昇することです。単純なクエリには約 15 秒かかり、結果が最初に切り取られるため、LIMIT を挿入しても修正されません。

CREATE VIEW CDR AS
(SELECT start,    duration, clid, FROM cdr_md ORDER BY start LIMIT 1000) 
 UNION ALL 
 (SELECT start,       duration, clid, FROM cdr_1025 ORDER BY start LIMIT 1000) 
 ORDER BY start ;

へのクエリ:

SELECT * FROM CDR WHERE start>10

期待される結果が返されないため、LIMIT キーワードが前の結果を切り捨てます。

期待される結果は、次のようなクエリになります。

CREATE VIEW CDR AS
(SELECT start,    duration, clid, FROM cdr_md WHERE start>X ORDER BY start LIMIT 1000) 
UNION ALL 
(SELECT start,    duration, clid, FROM cdr_1025 WHERE start>X ORDER BY start LIMIT 1000) 
 ORDER BY start ;

この問題を回避する方法はありますか? ありがとうファブリツィオ

4

1 に答える 1

0

私は2つの同様のテーブルを持っています...同じレイアウトで

これは、直交設計の原則に反します。

しないでください少なくとも、非常に正当な理由がないわけではありません。適切なインデックスがあれば、テーブルごとに 100 万レコードは、MySQL がパーティショニングなしで簡単に処理できます。また、データを分割する必要があったとしても、この手動のクラッジよりも優れた方法があります (あいまいで一貫性のないデータが発生し、データ操作コードの冗長性と複雑さが生じる可能性があります)。

代わりに、レコードの違いを区別するために、テーブルを適切な列を持つ 1 つのテーブルに結合することを検討してください。例えば:

CREATE TABLE cdr_combined AS
  SELECT *, 'md'   AS orig FROM cdr_md
UNION ALL
  SELECT *, '1025' AS orig FROM cdr_1025
;

DROP TABLE cdr_md, cdr_1025;

以前に「分割された」軸に沿ってデータを常に表示する場合は、識別列をインデックス プレフィックスとして含めると、通常、個別のテーブルを使用するよりもパフォーマンスが向上します。

その後、実行する必要はなくUNIONVIEW定義は効果的に次のようになります。

CREATE VIEW CDR AS
SELECT start, duration, clid, FROM cdr_combined ORDER BY start

ただし、ビューに対するクエリは、基になるテーブルを直接使用する場合と同じように常に実行されるとは限らないことに注意してください。ビューの制限の下に記載されているとおり:

ビューの処理が最適化されていません:

  • ビューにインデックスを作成することはできません。

  • インデックスは、マージ アルゴリズムを使用して処理されるビューに使用できます。ただし、temptable アルゴリズムで処理されるビューは、基になるテーブルのインデックスを利用できません (一時テーブルの生成中にインデックスを使用することはできますが)。

于 2013-07-18T11:23:22.070 に答える