美文网首页mysql
mysql优化实例

mysql优化实例

作者: 张一一 | 来源:发表于2015-03-31 12:42 被阅读208次

    优化原则

    过滤条件 尽可能前置

    连接时 索引先行

    临时表除非万不得已,慎用

    除非性能问题显现, 否则没有优化的必要。

    实例

    查询一台服务器对应的责任人,以及该服务器所属的产品。有以下表:

    server device_base cmdb_group ,node,user,resource_owner

    查询机器的主机名,ip,以及主机对应的owner以及机器所属的产品。

    优化前sql

    select

    id, hostname, mainIp, responsor, agentVersion, productName

    from

    (

    (select

    id,

    hostname,

    mainIp,

    group_concat(responsor) as responsor,

    agentVersion,

    productName

    from

    (

    (

    (

    select

    id, hostname, mainIp, agentVersion, productName, groupId

    from

    (

    (

    (select

    server.id as id,

    device_base.host_name as hostname,

    device_base.main_ip as mainIp,

    server.agent_version as agentVersion

    from

    server, device_base

    where

    server.id = device_base.id

    ) t_server_base

    )

    left join

    (

    (

    select

    server.id as serverId,

    server.group_id as groupId,

    cmdb_group.group_name as groupName,

    product.id as productId,

    product.node_name as productName

    FROM

    server, cmdb_group, node as grp, node as product

    where

    server.group_id = cmdb_group.id

    and cmdb_group.id = grp.id

    and grp.parent_id = product.id

    ) t_group

    ) ON t_server_base.id = t_group.serverId)

    )

    t_server)

    left join

    (

    (

    select

    user.user_name as responsor,

    cmdb_group.group_name as groupName,

    cmdb_group.id as groupId

    from

    user, cmdb_group, resource_owner

    where

    user.id = resource_owner.user_id

    and resource_owner.resource_id = cmdb_group.id

    and resource_type = 'group'

    )t_resource_user_group

    ) ON t_server.groupId = t_resource_user_group.groupId

    )

    group by id

    ) t_group)

    sql解释

    1、查服务器名和ip 版本号

    2、查服务器分组

    3、查分组负责人

    然后 三表 连接 后 ,形成临时表 t,在对该临时表进行查询。

    优化之后

    select server.id as id,host_name as hostname,main_ip as mainIp ,group_concat(user_name) as responsor,agent_version as agentVersion, product.node_name as productName

    from

    server join device_base on server.id=device_base.id

    join cmdb_group on server.group_id = cmdb_group.id

    join node on cmdb_group.id = node.id

    left join resource_owner on resource_owner.resource_id = cmdb_group.id

    join user on user.id =resource_owner.user_id

    left join node as product on product.id=node.parent_id

    where resource_type="group" and product.node_type = "product"

    group by server.id

    having group_concat(user_name) like concat('%', '', '%');

    优化前

    优化后

    优化之前,耗时500ms,优化后,耗时16ms。

    分析:

    1、优化之后的sql里增加了resource_type和node_type的筛选条件;筛选条件缩小规模。

    2、将子查询全部变为连接。好处是,子查询中,索引,key等都失效,但连接时,索引仍有效。

    注:可以将where里的条件提到 join的on语句处。

    何时会产生临时表

    1、子查询。

    2、order by和group by条件不同。比如group by priceorder by name。

    3、连接查询时,group by 或者 order by的列不是第一个长表里的列。

    select * from tableA,tableB,tableC group by tableB.gender

    4、order by的字段有distinct。如order by distinct(name)。

    5、使用union的会话。

    sql的查询执行顺序

    wheregroup byhavingorder by

    先用where进行过滤,然后对过滤出来是记录进行分组,之后再对group by的结果进行having筛选,最后order by。

    其他有助于数据库性能建议

    尽量使用固定长度的字段。因此char优于varchar。

    在大的delete或是insert语句时,防止长时间锁表。可以分成多次去执行。

    尽可能地使用not null。

    varchar不要超过65535,否则,变为mediumtext类型。

    相关文章

      网友评论

        本文标题:mysql优化实例

        本文链接:https://www.haomeiwen.com/subject/vbgixttx.html