*为与*动云做的云计算框架的sql优化

原语句:
SELECT
    ifnull(system_name, "ALL") AS system_name,
    ifnull(DISK, 0) AS disk
FROM
    (
        SELECT
            ROUND(SUM(disk_per) / COUNT(*), 4) AS DISK,
            s1.SYSTEM_ID
        FROM
            vm_info_tab p1
        LEFT JOIN (
            SELECT
                ROUND(
                    (
                        ifnull(SUM(disk_total), disk_free) - SUM(disk_free)
                    ) / SUM(disk_total),
                    4
                ) * 100 AS disk_per,
                per_hid
            FROM
                x86.vm_performance_tab f1
            WHERE
                f1.Per_Time > TIMESTAMPADD(WEEK, - 1, NOW())
            GROUP BY
                per_hid
        ) AS perf_value ON p1.ip = perf_value.per_hid
        LEFT JOIN system_device_relation_tab s1 ON p1.vm_id = s1.DEVICE_ID
        GROUP BY s1.`SYSTEM_ID`
    ) p1
LEFT JOIN system_info_tab p2 ON p1.system_id = p2.`system_id`;

+-------------+--------+
| system_name | disk |
+-------------+--------+
| ALL | 0.0000 |
+-------------+--------+
1 row in set (6.30 sec)      <--------- 0条记录使用了 6.30秒

1. 最大问题在于 join 后进行 group by ,  两表 join时候会有很多数据进行匹配 , group 有去重功能 , 可以先对数据进行去重 , 然后再进行join , 这样减少join数据时候比对量 , 并且用上了索引了 , 原语句只用了join 字段时候的索引 , 最后group by就要从表返回数据,这就是慢的原因之一 , 第3个操作就是用了 using where 过滤元组和是否读取数据文件或索引文件没有关系 , mysql官档:

Using where
A WHERE clause is used to restrict which rows to match against the next table or send to the client. Unless you specifically intend to fetch or examine all rows from the table, you may have something wrong in your query if the Extra value is not Using where and the table join type is ALL or index.

2. 分析后主要有2个表进行group by , f1 和 s1 表

修改后:
SELECT
    ifnull( system_name, "ALL" ) AS system_name,
    ifnull( DISK, 0 ) AS disk 
FROM
    (
    SELECT
        ROUND( SUM( disk_per ) / COUNT( * ), 4 ) AS DISK,
        s1.SYSTEM_ID 
    FROM
        vm_info_tab p1
        LEFT JOIN (
        SELECT
            ROUND( ( ifnull( SUM( disk_total ), disk_free ) - SUM( disk_free ) ) / SUM( disk_total ), 4 ) * 100 AS disk_per,
            per_hid 
        FROM
            (
            SELECT
                disk_total,
                disk_free,
                per_hid 
            FROM
                x86.vm_performance_tab f1
                INNER JOIN ( SELECT id FROM x86.vm_performance_tab f1 GROUP BY per_hid ) a ON f1.id = a.id 
            WHERE
                f1.Per_Time > TIMESTAMPADD (
                    WEEK, - 1,
                NOW ()) 
            ) f1 
        GROUP BY
            f1.per_hid 
        ) AS perf_value ON p1.ip = perf_value.per_hid
        LEFT JOIN system_device_relation_tab s1 ON p1.vm_id = s1.DEVICE_ID 
    GROUP BY
        s1.` SYSTEM_ID ` 
    ) p1
    LEFT JOIN system_info_tab p2 ON p1.system_id = p2.` system_id `;

+-------------+--------+
| system_name | disk |
+-------------+--------+
| ALL | 0.0000 |
+-------------+--------+
1 row in set (0.41 sec)      <------- 性能上来了

3. f1 字段使用 索引进行group by , 第5操作 , 提升了性能

猜你喜欢

转载自www.cnblogs.com/kelvin19840813/p/10464308.html