栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

结合UNIOn ALL的表的VIEW的MySQL性能

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

结合UNIOn ALL的表的VIEW的MySQL性能

我同意Bill Karwin的出色回答中的所有观点。

问: 为讨论的联合查询创建视图并在我的联接,子选择等中使用它是正常的做法吗?

答: 对于MySQL,更常见的做法是避免使用“ CREATE VIEW”语句。

问: 就性能而言-与仅将其插入联接,子选择等中相比,会更差,是否相等或更好?

答: 引用视图对象将具有与等效的嵌入式视图相同的性能。

(查找视图对象,检查特权,然后用存储的SQL替换视图引用可能要花更多的时间,而发送的语句要长得多。差异微不足道。)

问: 在这种情况下,有视图有任何弊端吗?

答:
最大的缺点是MySQL如何处理视图(无论是存储视图还是内联视图)。MySQL将始终运行视图查询并将该查询的结果具体化为临时MyISAM表。但是,无论是存储视图定义还是内联包含视图定义都没有什么区别。(其他RDBMS处理视图的方式与MySQL截然不同)。

视图的一大缺点是,外部查询的谓词永远不会下推到视图查询中。每次引用该视图时,即使使用单个id值查询,MySQL都将运行该视图查询并创建一个临时MyISAM表(上面没有索引),然后MySQL将对该临时表运行外部查询MyISAM表。

因此,就性能而言,请考虑对与“

CREATE TEMPORARY TABLE t (cols) ENGINE=MyISAM
”和“
INSERTINTO t (cols) SELECt ...
”相提并论的观点的引用。

MySQL实际上将内联视图称为“派生表”,当我们了解MySQL在做什么时,该名称很有意义。


我个人的喜好是不要使用“ CREATE
VIEW”语句。最大的缺点(如我所见)是它“隐藏”了正在执行的SQL。对于将来的读者来说,对该视图的引用就像一张表。然后,当他去编写SQL语句时,他将像表一样引用视图,因此非常方便。然后,他决定要将该表与自身连接,并对其进行另一个引用。(作为第二参考,MySQL还再次运行该查询,并创建了另一个临时(且未建立索引)MyISAM表。现在,在该表上执行了JOIN操作。然后添加了谓词“
WHERe view.column =’foo’”在外部查询上。

最后,它“隐藏”了最明显的性能改进,使谓词滑入视图查询。

然后,有人来决定他们要创建引用旧视图的新视图。他只需要一部分行,并且不能修改现有视图,因为这可能会破坏某些内容,因此他创建了一个新视图…从publicview创建视图myview
p在哪里p.col =’foo’。

并且,现在,对myview的引用将首先运行publicview查询,创建一个临时MyISAM表,然后针对该myview查询运行,创建另一个临时MyISAM表,外部查询将针对该表运行。

基本上,视图的便利性可能会导致意外的性能问题。数据库中的视图定义可供任何人使用,即使不是最合适的解决方案,也将有人使用。

至少在内联视图中,编写SQL语句的人员更了解实际正在执行的SQL,并且将所有SQL布局都可以对其进行调整以提高性能。

我的两分钱。

驯服SQL

我发现,应用常规的格式设置规则(我的工具会自动执行)可以将庞杂的SQL变成我可以阅读和使用的东西。

SELECT row.col1     , row.col2     , person.*  FROM some_table row  LEFT  JOIN ( SELECt 'person'  AS `person_type`   , p.id      AS `id`   , CONCAt(p.first_name,' ',p.surname) AS `name`FROM person p          UNIOn ALL         SELECt 'company' AS `person_type`   , c.id      AS `id`   , c.name    AS `name`FROM company c       ) person    ON person.id = row.person_id   AND person.person_type = row.person_type

我同样有可能完全避免使用内联视图,并在SELECt列表中使用条件表达式,尽管对于许多列而言,这样做确实更加麻烦。

SELECT row.col1     , row.col2     , row.person_type AS ref_person_type     , row.person_id   AS ref_person_id     , CASE       WHEN row.person_type = 'person'  THEN p.id        WHEN row.person_type = 'company' THEN c.id       END AS `person_id`     , CASE       WHEN row.person_type = 'person'  THEN CONCAt(p.first_name,' ',p.surname)       WHEN row.person_type = 'company' THEN c.name       END AS `name`  FROM some_table row  LEFT  JOIN person p    ON row.person_type = 'person'   AND p.id = row.person_id  LEFT  JOIN company c    ON row.person_type = 'company'   AND c.id = row.person_id


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/400241.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号