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?目标是有一个视图,它返回equalsanother_table所在的行数。 other_column'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 回答