在mysql视图中,从union开始还是以union结束更快?

pdkcd3nj  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(369)

我的数据库有多个表,其中有一些匹配的列,但名称和顺序不同。
例如

Table1:   FullName Grade Foo
Table2:   Bar Rank WholeName

什么会更快:
1) 1个视图,对每个表重复相同的查询

CREATE View Test AS
  SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(FullName, ' ', 1), ' ', -1) AS "First Name",
         If (Grade<50, "Bad", "Good") AS "Type"
    FROM table1
  UNION
  SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(WholeName, ' ', 1), ' ', -1) AS "First Name",
         If (Rank<50, "Bad", "Good") AS "Type"
    FROM table2


2) 两个视图,一个用于纯合并,另一个用于操纵

CREATE View Test1 AS
SELECT FullName AS "First Name", Grade AS "Type"
FROM table1
UNION
SELECT WholeName AS "First Name", Rank AS "Type"
FROM table2

CREATE View Test2 AS
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`First Name`, ' ', 1), ' ', -1) AS "First Name",
If (Type<50, "Bad", "Good") AS "Type"
FROM Test1

显然1)更复杂,因为你必须重复每一个操作。如果你有10张table,那就意味着重复同样的操作10次。如果你有10个操作,那就意味着写100个操作而不是10个。但如果快一点,我就买。
http://www.sqlfiddle.com/#!9/48d531/1表示大致相同的时间,尽管在某些运行中它支持2)。
请记住,这里涉及到大量的数据,而实际的sql非常复杂,并且涉及左连接。

7qhs6swi

7qhs6swi1#

VIEW 是语法上的糖分--试试等价的 SELECT .
“sugar”论点认为q2在解决了 VIEWs :

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`First Name`,
               ' ', 1), ' ', -1) AS "First Name",
           If (Type<50, "Bad", "Good") AS "Type"
    FROM ( SELECT .. UNION SELECT .. )
``` `FROM ( ... )` 称为“派生”表。它通常变成一个临时表,从中执行其余的select操作。这是一个额外的,中等重量,步骤是避免在第一季度。
实际上,您可能不会注意到性能上的差异。
从5.7.6变更日志:
要处理派生表(from子句中的子查询)或视图引用,优化器可以具体化对内部临时表的派生表或视图引用,或将其合并到外部查询块中。以前,派生表总是具体化的,而等价的视图引用有时具体化,有时合并。对等价查询的这种不一致的处理可能会导致性能问题:不必要的派生表具体化需要时间,并阻止优化器将条件下推到派生表。
这意味着你的问题的答案取决于你使用的mysql版本。 `UNION` 5.7.3中的优化:
服务器不再为满足某些限定条件的union语句使用临时表。相反,它从临时表创建中只保留执行结果列类型转换所需的数据结构。表没有完全示例化,没有向其中写入或从中读取任何行;行直接发送到客户机。结果是减少了内存和磁盘需求,并且在将第一行发送到客户机之前减少了延迟,因为服务器不需要等到执行最后一个查询块。解释和优化器跟踪输出将更改:联合结果查询块将不存在,因为该块是从临时表中读取的部分。。。错误#50674

相关问题