处理视图的MySQL Temp Table算法

Kho*_*rak 5 mysql algorithm merge views temp-tables

如果将Temp Table算法重命名为Unscalable算法会很好.当在视图定义中看到它时,它可能会给开发人员提供更多警告 - 类似于在解释结果中使用临时表时.在大多数情况下只是一个诙谐的请求,但实际上它对于不知情的人来说是灾难性的.

麻烦的是,如果你在视图定义中做某些事情,它将从合理的合并算法切换到无望的低效临时表算法.如果涉及的数据很少,这没什么大不了的.但是,随着数据的增长,这将会破坏您的性能.

尽管如何最好地处理这个问题?这是一个问题,因为观点是在5年前实施的,我不知道有任何修复它的努力.这种问题是否存在于其他流行的数据库系统中?

向下滚动到下面的链接,讨论何时不能使用合并算法来查看导致MySQL使用糟糕的Temp Table算法退化的原因:http: //mysql2.mirrors-r-us.net/doc/refman/ 5.1/EN /创建-view.html

这有什么不好的?临时表算法的工作原理如下:

  1. 在视图定义中"按原样"运行视图,而不将查询的where子句标准合并到其中.
  2. 将结果数据转储到临时表中.
  3. 根据查询的where子句标准过滤临时表中的数据 - 此处也没有索引.

所以你可以想象当你有一个5000万行表和一个视图定义时所涉及的地狱 - 愚蠢的例子,但你得到了重点:

create view last_order_date as 
    select max(order_date) last_date, username from orders group by username;
Run Code Online (Sandbox Code Playgroud)

然后用户可以写:

select * from last_order_date where username = 'joejoe22' 
Run Code Online (Sandbox Code Playgroud)

2小时后返回结果......

那么如何最好地应对这种情况呢?

Joh*_*ica 3

编写一个返回结果集的存储过程。

DELIMITER $$

CREATE PROCEDURE DoViewMyData(Param1 INT)
BEGIN
  SELECT 
    field1 as x
    ,field2 as y
    FROM table
    WHERE field1 = Param1;
END$$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

现在调用该过程,它将返回其中的 select 语句的结果集。

CALL DoViewMyData(1);

OUTPUT:
+------+-------------------+
| x    | y                 |
+------+-------------------+
| 1    | balabablabla      |
+------+-------------------+
Run Code Online (Sandbox Code Playgroud)

只做CALL,不做,这样SELECT CALL是行不通的。
您也不能另一个 SELECT 语句中使用CALL
当然,您可以指示存储过程将输出放入临时表中,然后在另一个 SELECT 中使用它。

存储过程将使用正确的索引,并且您的 select 语句已准备好。
另外,您可以在前面的语句中准备一些内容,从而加快时间关键的查询。

不过你是对的: MySQL 视图确实很糟糕