【发布时间】:2018-06-15 07:38:25
【问题描述】:
我的数据库有多个表,其中有一些匹配的列,但名称和顺序不同。
例如
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) 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 张桌子,那就意味着重复同样的操作 10 次。如果你有 10 个操作,那就意味着要编写 100 个操作而不是 10 个。但如果它更快,我会接受。
http://www.sqlfiddle.com/#!9/48d531/1 建议的时间大致相同,尽管在某些运行中它倾向于 2)。
请记住,其中涉及大量数据,实际 SQL 非常复杂,并且涉及 LEFT JOIN。
【问题讨论】:
-
无视图 > 1 视图 > 2 视图。每个级别的视图都将限制 MySQL 优化查询的选项(例如,在评估每一行之前使用索引或连接或过滤)。您正在尝试通过应用视图来修复您的数据库模型,这将变得混乱/缓慢。想法:a)将名称直接存储在 2 个字段中 b)将所有名称存储在“用户”表中,并在 2 个表中使用 id(删除
union)c)在中显示内容(“好”/“坏”)您的前端或最外面的查询。现在您有 0 次观看。如果实际的 sql 更复杂,则类似的修复/注意事项更加相关。 -
修复模型是对的,但表来自不同的来源,具有不同的列名。对我来说,比 1 个视图快于 2 个视图听起来很合理,那么 sqlfiddle 怎么会显示我写的内容呢?不知道 a) 和 b) 是什么意思,也许用 sqlfiddle 来演示?不知道为什么 c) 会更快,SQL 是在服务器中完成的,所以我认为使用另一个服务器过程甚至更糟的是客户端没有任何好处。
-
20 行表的执行时间除了随机中断如何影响执行时间之外,不会为您提供任何有价值的信息。视图(在 mysql 中)不能比非视图快,它只是缩短了 sql 代码:视图的代码实际上会放在您使用视图的任何地方。我的意思是:您当然可以使用视图来修复您的模型(例如,动态拆分名称而不是首先在 2 列中的“名字”、“姓氏”),但正如您已经看到的那样,它使事情其实更复杂。每次优化的第一步都是干净的数据和干净的数据模型。
标签: mysql performance view