mysql视图优化,多表关联视图,我在查询的时候很慢,该怎么优化????

SELECT
stu.id AS id,
stu.enrollment_date AS enrollment_date,
stu.`name` AS `name`,
stu.periods AS periods,
stu.id_number AS id_number,
stu.archives_number AS archives_number,
stu.header AS header,
stu.birthday AS birthday,
stu.contact_address AS contact_address,
stu.home_address AS home_address,
stu.physical_examination AS physical_examination,
stu.company AS company,
stu.position AS position,
stu.have_car AS have_car,
stu.gender AS gender,
stu.age AS age,
stu.apply_type AS apply_type,
stu.mobile AS mobile,
stu.state AS state,
stu.graduation_time AS graduation_time,
stu.period_of_validity AS period_of_validity,
stu.period AS period,
stu.remark AS remark,
dept.`name` AS dep_name,
dept.parent_id AS dept_parent_id,
dept.id AS dept_id,
dot.id AS dot_id,
dot.dot_name AS dot_name,
student_field_coach.field_coach_id AS field_coach_id,
student_field_coach.field_coach_name AS field_coach_name,
student_road_coach.road_coach_id AS road_coach_id,
student_road_coach.road_coach_name AS road_coach_name,
service_type.id AS service_type_id,
service_type.service_type_name AS service_type_name,
service_type.service_type_cost AS service_type_cost,
stu.add_drive AS add_drive,
stu.operator AS operator,
entry_way.entry_way,
entry_way.id AS entry_way_id,
stu.create_time,
stu.update_time
FROM
((((((((((student AS stu
LEFT JOIN student_department ON ((stu.id = student_department.student_id)))
LEFT JOIN department AS dept ON ((dept.id = student_department.department_id)))
LEFT JOIN student_dot ON ((stu.id = student_dot.student_id)))
LEFT JOIN dot ON ((dot.id = student_dot.dot_id)))
LEFT JOIN student_field_coach ON ((student_field_coach.student_id = stu.id)))
LEFT JOIN staff_info AS field ON ((student_field_coach.field_coach_id = field.id)))
LEFT JOIN student_road_coach ON ((student_road_coach.student_id = stu.id)))
LEFT JOIN staff_info AS road ON ((student_road_coach.road_coach_id = road.id)))
LEFT JOIN student_service_type ON ((student_service_type.student_id = stu.id)))
LEFT JOIN service_type ON ((student_service_type.service_type_id = service_type.id)))
LEFT JOIN entry_way on entry_way.id=stu.entry_way

这么多的join你应该是在数据库设计的时候表结构设计的不够好 - 建议采用后台数据同步的方式批量将数据整合进一张表中后定期刷新数据来平衡性能上的需求。
温馨提示:内容为网友见解,仅供参考
第1个回答  2020-06-01

MySQL 8.0 推出了histogram,也叫柱状图或者直方图。先来解释下什么叫直方图。


关于直方图

我们知道,在DB中,优化器负责将SQL转换为很多个不同的执行计划,完了从中选择一个最优的来实际执行。但是有时候优化器选择的最终计划有可能随着DB环境的变化不是最优的,这就导致了查询性能不是很好。比如,优化器无法准确的知道每张表的实际行数以及参与过滤条件的列有多少个不同的值。那其实有时候有人就说了,索引不是可以解决这个问题吗?是的,不同类型的索引可以解决这个问题,但是你不能每个列都建索引吧?如果一张表有1000个字段,那全字段索引将会拖死对这张表的写入。而此时,直方图就是相对来说,开销较小的方法。

直方图就是在 MySQL 中为某张表的某些字段提供了一种数值分布的统计信息。比如字段NULL的个数,每个不同值出现的百分比、最大值、最小值等等。如果我们用过了 MySQL 的分析型引擎brighthouse,那对这个概念太熟悉了。

MySQL的直方图有两种,等宽直方图和等高直方图。等宽直方图每个桶(bucket)保存一个值以及这个值累积频率;等高直方图每个桶需要保存不同值的个数,上下限以及累计频率等。MySQL会自动分配用哪种类型的直方图,我们无需参与。

MySQL 定义了一张meta表column_statistics 来存储直方图的定义,每行记录对应一个字段的直方图,以json保存。同时,新增了一个参数histogram_generation_max_mem_size来配置建立直方图内存大小。

不过直方图有以下限制:

1. 不支持几何类型以及json。2. 不支持加密表和临时表。3. 不支持列值完全唯一。4. 需要手工的进行键值分布。

那我们来举个简单的例子说明直方图对查询的效果提升。


举例

表相关定义以及行数信息等:

    mysql> show create table t2\G

    *************************** 1. row ***************************

    Table: t2

    Create Table: CREATE TABLE `t2` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `rank1` int(11) DEFAULT NULL,

    `rank2` int(11) DEFAULT NULL,

    `rank3` int(11) DEFAULT NULL,

    `log_date` date DEFAULT NULL,

    PRIMARY KEY (`id`),

    KEY `idx_rank1` (`rank1`),

    KEY `idx_log_date` (`log_date`)

    ) ENGINE=InnoDB AUTO_INCREMENT=49140 DEFAULT CHARSET=utf8mb4 \

    COLLATE=utf8mb4_0900_ai_ci STATS_PERSISTENT=1 STATS_AUTO_RECALC=0

    1 row in set (0.00 sec)

    mysql> select count(*) from t2;

    +----------+

    | count(*) |

    +----------+

    | 30940 |

    +----------+

    1 row in set (0.00 sec)

    同时对t2克隆了一张表t3

    mysql> create table t3 like t2;

    Query OK, 0 rows affected (0.13 sec)

    mysql> insert into t3 select * from t2;

    Query OK, 30940 rows affected (1.94 sec)

    Records: 30940 Duplicates: 0 Warnings: 0

    给表t3列rank1和log_date 添加histogram

    mysql> analyze table t3 update histogram on rank1,log_date;+--------+-----------+----------+-----------------------------------------------------+| Table | Op | Msg_type | Msg_text |+--------+-----------+----------+-----------------------------------------------------+| ytt.t3 | histogram | status | Histogram statistics created for column 'log_date'. || ytt.t3 | histogram | status | Histogram statistics created for column 'rank1'. |+--------+-----------+----------+-----------------------------------------------------+2 rows in set (0.19 sec)


    我们来看看histogram的分布状况

    mysql> select json_pretty(histogram) result from information_schema.column_statistics where table_name = 't3' and column_name = 'log_date'\G*************************** 1. row ***************************result: { "buckets": [ [ "2018-04-17", "2018-04-20", 0.01050420168067227, 4 ], ... , [ "2019-04-14", "2019-04-16", 1.0, 3 ] ], "data-type": "date", "null-values": 0.0, "collation-id": 8, "last-updated": "2019-04-17 03:43:01.910185", "sampling-rate": 1.0, "histogram-type": "equi-height", "number-of-buckets-specified": 100}1 row in set (0.03 sec)


    MySQL自动为这个字段分配了等高直方图,默认为100个桶。SQL A:

    select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';


    SQL A的执行结果:

    mysql> select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';+----------+| count(*) |+----------+| 2269 |+----------+1 row in set (0.01 sec)


    无histogram的执行计划

    mysql> explain format=json select count(*) from t2 where (rank1 between 1 and 10) and log_date < '2018-09-01'\G*************************** 1. row ***************************EXPLAIN: { "query_block": { "select_id": 1, "cost_info": { "query_cost": "2796.11" }, "table": { "table_name": "t2", "access_type": "range", "possible_keys": [ "idx_rank1", "idx_log_date" ], "key": "idx_rank1", "used_key_parts": [ "rank1" ], "key_length": "5", "rows_examined_per_scan": 6213, "rows_produced_per_join": 3106, "filtered": "50.00", "index_condition": "(`ytt`.`t2`.`rank1` between 1 and 10)", "cost_info": { "read_cost": "2485.46", "eval_cost": "310.65", "prefix_cost": "2796.11", "data_read_per_join": "72K" }, "used_columns": [ "rank1", "log_date" ], "attached_condition": "(`ytt`.`t2`.`log_date` < '2018-09-01')" } }}


    有histogram的执行计划

    mysql> explain format=json select count(*) from t3 where (rank1 between 1 and 10) and log_date < '2018-09-01'\G*************************** 1. row ***************************EXPLAIN: { "query_block": { "select_id": 1, "cost_info": { "query_cost": "0.71" }, "table": { "table_name": "t3", "access_type": "range", "possible_keys": [ "idx_rank1", "idx_log_date" ], "key": "idx_log_date", "used_key_parts": [ "log_date" ], "key_length": "4", "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", "index_condition": "(`ytt`.`t3`.`log_date` < '2018-09-01')", "cost_info": { "read_cost": "0.61", "eval_cost": "0.10", "prefix_cost": "0.71", "data_read_per_join": "24" }, "used_columns": [ "rank1", "log_date" ], "attached_condition": "(`ytt`.`t3`.`rank1` between 1 and 10)" } }}1 row in set, 1 warning (0.00 sec)

    我们看到两个执行计划的对比,有Histogram的执行计划cost比普通的sql快了好多倍。上面文字可以看起来比较晦涩,贴上两张图,看起来就很简单了。无histogram请点击输入图片描述有histogram请点击输入图片描述当然,我这里举得例子相对简单,有兴趣的朋友可以更深入学习其他复杂些的例子。

mysql视图优化,多表关联视图,我在查询的时候很慢,该怎么优化???
这么多的join你应该是在数据库设计的时候表结构设计的不够好 - 建议采用后台数据同步的方式批量将数据整合进一张表中后定期刷新数据来平衡性能上的需求。

优化MySQL三表联查提升查询效率mysql三表联查效率
1. 缩小查询范围:尽可能减少查询条件的范围,以缩短查询时间。例如,在三表联查中,可以先通过WHERE子句对第一个表进行过滤,以减少JOIN操作的数量。2. 添加索引:在多表联查中,可以为关联列添加索引,以加快JOIN操作的速度。同时,在使用SELECT语句时,也应该使用优化的索引顺序,以提高查询效率。MySQL...

优化MySQL查询减少两表联查的耗时mysql两表联查耗时
在使用MySQL进行查询时,对表建立索引是必不可少的。索引可以加快查询速度,从而提高查询效率和性能。在进行两表联查时,我们需要使用适当的索引来减少数据的扫描,提高查询速度。具体方法如下:1.使用联合索引 联合索引是一种使用多个列组合在一起的索引。它能够对多个列进行排序,并且在查询时只需要使用...

MySQL数据库性能优化方法,一篇给你总结了!
使用视图加速查询:创建视图简化优化器工作,减少磁盘I\/O,提升查询效率。算法优化:避免游标,优先考虑基于集的方法或使用存储过程。通过上述策略,可以有效提升MySQL数据库性能,实现高效数据处理。优化需全局考虑,避免局部调整影响整体性能。

MySQL视图提升数据处理效率mysql视图的效率
(1)视图性能:MySQL视图有一定的性能损耗,由于视图会占用系统资源,因此,在创建视图时,应尽可能缩短视图语句,以提高视图的查询性能。(2)视图的存储:MySQL视图只能存储记录,比如字段,不能存储索引或默认值,因此,需要谨慎分析选择存储视图的数据库,避免在分发时出现问题。综上所述,MySQL视图是...

MySQL视图查询超慢,求解答
时间的快慢主要由索引决定,在索引都最优化的情况下才与数据量有关。视图不可能明显加快的查询速度,只是编程方便而已。

MySQL一键优化简单快捷的数据库性能提升方法mysql一键优化
2. MySQL Performance Tuning Primer MySQL Performance Tuning Primer是另一个很好用的工具,它可以提供有关您MySQL配置的详细信息,例如缓存设置、连接池、查询构建、磁盘操作和内存利用率等。它可以根据您的实际用例自动为您提供一些优化建议,以改善性能和可用性。要使用MySQL Performance Tuning Primer,请...

sql语句查询时间过长怎么优化?
数据库架构优化包括分布式和集群化,通过负载均衡集群,将读和写操作分离,减轻数据库压力和IO压力,实现负载均衡。主数据库负责写操作,从数据库负责读操作,通过路由规则访问特定数据库,降低单台机器负载压力。使用视图加速查询,将表子集进行排序并创建视图,简化优化器工作,减少磁盘I\/O。避免使用游标,...

MySQL数据表中的一千列数据的优化方法mysql一千列数据
7. 合理使用缓存 缓存可以帮助加快查询速度和提高数据表的性能。对于包含一千列以上的数据表,应该合理使用内存缓存和查询缓存,以避免频繁访问磁盘而导致的性能问题。综上所述,对于包含一千列以上的数据表,可以采取上述优化方法来提高整个系统的性能。此外,还可以使用性能分析工具来诊断和优化数据库的性能...

MySQL实现一对多关系的视图mysql一对多视图
3. 如果源表数据量非常大,那么创建视图可能会导致性能问题。在这种情况下,可以考虑将视图拆分为多个较小的视图,或者使用其他方法来优化查询性能。使用视图可以简化查询过程,并提高查询性能。对于一对多关系,使用JOIN和SELECT语句创建视图可以将相关数据合并在一起,方便了数据的获取和管理。

相似回答