• Mysql视图的作用及其性能分析


    定义:视图是从一个或几个基本表导出的表,它与基本表不同,是一个虚表。

    作用:

      1.简化操作,不用进行多表查询。

      2.当不同种类的用用户共享同一个数据库时,非常灵活,(用户以不同的

    方式看待同一数据. 

      3.视图对重构数据库提供了一定程度的逻辑独立性。

     数据的逻辑独立性是指:如增加新的关系或对原有的关系增加新的

    字段,用户的应用程序不受影响.

     例如:原有一个Student(Sno,Sname,Ssex,Sage,Sdept)这样一个表.

         后来变动为:Sx(Sno,Sname,Sage)和SY(Sno,Ssex,Sdept)

    两个表。

        这时候原表Student为SX和SY表自然连接的结果。

    那么如果我们一开始建立了一个试图:

     create view Student(Sno,Sname,Ssex,Sage,Sdept)

    as  select SX.Sno,SX.Sname,SY.Ssex,SX,Sage,SY,Sdept

    from SX,SY  where SX.Sno=SY.Sno;

     尽管数据库的逻辑结构改变了,但是应用程序不必修改(因为这个这个

    视图所定义的关系没有变啊)。 

    【注意:试图只能在一定程度上提供数据的逻辑独立,比如由于

    视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会

    因为基本表构造的改变而改变.

     4. 视图能够对机密数据提供安全保护 

       有了视图机制,就可以在设计数据库应用系统时,对不同的用户定义不同的视图,使机密数据不出现在不应该看到这些数据 的用户视图上。这样视图机制就自动提供了对机密数据的安全保护功能。例如,Student表涉及全校15个院系学生数据,可以在其上定义15个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本原系学生视图。

      5、适当的利用视图可以更清晰地表达查询

        例如经常需要执行这样的查询“对每个学生找出他获得最高成绩的课程号”。可以先定义一个视图,求出每个同学获得的最高成绩:
    CREATE VIEW VMGRADE
    AS
    SELECT Sno,MAX(Grade) Mgrade
    FROM SC
    GROUP BY Sno;
    然后用如下的查询语句完成查询:

    SELECT SC.Sno,Cno FROM SC,VMGRADE WHERE SC.Sno = VMGRADE.Sno AND SC.Grade = VMGRADE.Mgrade;

     MySql视图的算法及其性能分析:

            mysql在处理视图时有两种算法,分别称为merge和temptable。

    在执行“create view”语句时可以指定使用哪种算法,所谓merge是指在

    处理涉及到视图的操作时,将对视图的操作根据视图的定义进行展开,有点类似于

    c语言中的宏展开. 

       例如设有以下表: 

     CREATE TABLE `comment` (
      `id` int(11) NOT NULL,
      `user_id` int(11) default NULL,
      `content` varchar(255) default NULL,
      PRIMARY KEY  (`id`),
      KEY `idx_comment_uid` (`user_id`)
    ) ENGINE=InnoDB;
    假设user_id < 10000的用户为VIP用户,我们可以这样创建一个视图来表示VIP用户的评论:
    CREATE VIEW vip_comment AS SELECT * FROM comment WHERE user_id < 10000;
    这时我们在操作vip_comment视图时使用的就是MERGE算法

    【一般在能够使用merge算法的时候mysql处理视图上没什么性能问题,

    但并非在任何时候都能使用merge算法.事实上,只要视图的定义稍稍有点复杂,mysql就没办法使用merge算法了.准确的说,只要视图定义中

    使用了一下sql构造块就无法使用merge算法:

       (1)聚集函数(2)distinct (3)group by (4)having 

    (5)having (6)集合操作(在mysql只有union,union all,没有except和intersect)(7)子查询.】


    确实,在视图定义比较复杂的情况下,要对视图操作进行有效的优化是非常困难的。因此在这个时候,MySQL使用了一种以不变应万变的方法,即先执行视图定义,将其结果使用临时表保存起来,这样后续对视图的操作就转化为对临时表的操作。不能不说从单从软件设计的角度看,这样的方法非常的优雅,然而从性能角度,这一方法也是非常的差。

             比如我们希望使用如下的视图来表示每个用户的评论数,即:

          CREATE VIEW comment_count AS SELECT user_id, count(*) AS count FROM comment GROUP           BY user_id;

           使用这个视图的时候,我们可能心里有个小算盘。目前我们先用这个视图顶着,如果性能确实有问题,那我们就        再来搞一张comment_count的表,其中就记下来每个用户的评论数。而我们现在先用这个视图是为了将来要          是改的话会方便点(这也是视图--即教科书中所谓的外模式--这个东西存在的主要原因之一,另一主要原因是          便于权限控制)。但是遇到了MySQL这个蠢货,我们的算盘铁定会失败。

           我们来看一下指定user_id从comment_count选取记录时的执行策略:

           mysql> explain select count(*) from comment_count where user_id = 90;

      可以看出,mysql首先是先执行comment_count的视图定义,

    将结果存储在临时表中,选择出满足"user_id=90”的那一条

    记录,这样,虽然我们最终只需要统计90号用户的评论数,并且comment

    表的user_id字段也有索引,mysql也会扫描整个comment表,并按

    user_id分组计算出所有用户的评论数。

    【这里面要注意的是即使在进行explain时,系统的物化也是要先执行的,

    因此若评论很多的话explain也是一样的慢。这个问题的根源是

    mysql的查询优化本来就存在很多问题.对于上述的查询,要达到比较

    好的优化效果在数据库中一般是如下处理的:

    1.将视图的操作转化为from字句中的子查询. 

    select * from (select user_id,count(*) as count from comment

    group by user_id)as comment_count where user_id=90;

    2.子查询提升。因为子查询中使用了group by,因此先将外面的条件

    作为提升后的having条件

    select user_id,count(*) as count from comment group by usr_id

    having user_id=90;

    3.由于having条件中不涉及聚集函数,转化为where条件

    select user_id ,count(*) as count from comment where user_id=90

    group by user_id;

    4.由于指定where条件后,user_id已经是一个常数,根据常数group by

    没有意义,因此去掉group by。

    select user_id,count(*) as count from comment where user_id=90

     除第4步无法根据EXPLAIN输出和查询性能判断出MySQL是否进行这一优化外,前3类优化MySQL都不会进行。因此,MySQL要能够有效的处理上述查询还有很长的路要走。


    PS: 相对来说PostgreSQL的查询优化能力就强得多,上面的查询在PostgreSQL中就能够产生上述优化后的最终执行计划。PostgreSQL比较关注查询优化估计与PostgreSQL的学院派风格或PostgreSQL中的rule system有关。










  • 相关阅读:
    百度指数感想
    冲刺贡献分
    冲刺三
    通过myEclipse创建hibernate的实体类
    并发处理
    数据库设计原则(转载)
    Extjs学习
    关于oracle存储过程需要注意的问题
    oracle存储过程
    十大编程算法
  • 原文地址:https://www.cnblogs.com/God-boy1/p/3916913.html
Copyright © 2020-2023  润新知