2

次のビューを検討してください

CREATE VIEW `my_view` AS
SELECT
    a.id,
    (SELECT
            COUNT( b.id )
        FROM
            another_table b
        WHERE
            b.a_id = a.id AND b.other_column = 'ABC'
    ) AS counter
FROM
    some_table a

some_table何百万もの行があり、 +another_tableにインデックスがあります。 a_idother_column

ここで、次の SQL を考えてみましょう。

SELECT vw.*
FROM some_table a
LEFT JOIN my_view vw on vw.id = a.id
WHERE a.id = 12345

この sql クエリが でフル テーブル スキャンを実行している理由を誰か教えてもらえますsome_tableか? another_table目標は、other_columnequalsから行数を返すビューを持つことです'ABC'

LEFT JOIN my_viewクエリをに置き換えるとLEFT JOIN ( the AS CLAUSE from the view )、完全なテーブル スキャンは実行されず、a_id + other_column インデックスが使用されます。

私は困惑しています。どんな助けでも大歓迎です。

4

1 に答える 1

1

通常、MySQL のビュー。. . 【そんな言葉使いたくない . . . 人が期待する、または望むほどうまく機能しない。「ああ、SQL エンジンはビュー定義をクエリにプラグインして最適化するだけだろう」とあなたは考えます。あなたは完全に間違っているわけではありません。MySQL はそれを行います。これは、ビューの MERGE アルゴリズムと呼ばれます。

残念ながら、MERGE アルゴリズムを使用できる有用なビューは多くありません。基本的に、フィールドの名前を変更し、単一のテーブルで式を事前計算するために使用できます。

代替アルゴリズムは TEMPTABLE アルゴリズムです。ご覧のとおり、これにより一時テーブルが作成されるため、テーブル全体のスキャンが行われます。

もちろん、これについてはドキュメントで詳しく読むことができます。

簡単な回避策はないと思います。サマリー テーブルを作成し、トリガーを使用して最新の状態に保つことができます。しかし、私はそれを「単純」とは考えていません。

于 2014-11-10T19:37:56.637 に答える