为什么从视图和该视图的底层select检索数据时会有性能差异

9jyewag0  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(282)

我正在用单个 predicate 对视图进行查询,这会在4-7秒内给出记录,但是当我尝试用相同的 predicate 直接从该视图的基础查询检索记录时,它会在不到几秒钟内给出记录。我正在使用mysql。
我试过检查这两个查询的执行计划,如果表中有成百上千条记录,它会给出主要的区别。
那么,有什么线索或想法可以解释为什么直接使用查询时性能更好呢?
下面是我的视图定义

SELECT    entity_info.source_entity_info_id      AS event_sync_id, 
          entity_info.source_system_id           AS source_system_id, 
          entity_info.target_system_id           AS destination_system_id, 
          event_sync_info.integrationid          AS integration_id, 
          event_sync_info.source_update_time     AS last_updated, 
          entity_info.source_internal_id         AS source_entity_internal_id, 
          entity_info.source_entity_project      AS source_entity_project, 
          entity_info.target_internal_id         AS destination_entity_internal_id, 
          entity_info.destination_entity_project AS destination_entity_project, 
          entity_info.source_entity_type         AS source_entity_type, 
          entity_info.destination_entity_type    AS destination_entity_type, 
          event_sync_info.opshub_update_time     AS opshub_update_time, 
          event_sync_info.entity_info_id         AS entity_info_id, 
          entity_info.global_id                  AS global_id, 
          entity_info.target_entity_info_id      AS target_entity_info_id, 
          entity_info.source_entity_info_id      AS source_entity_info_id, 
          ( 
                 SELECT Count(0) AS count(*) 
                 FROM   ohrv_failed_event_view_count failed_event_view 
                 WHERE  (( 
                                      failed_event_view.integration_id = event_sync_info.integrationid)
                        AND    ( 
                                      failed_event_view.entityinfo = entity_info.source_entity_info_id))) AS no_of_failures
FROM      (ohrv_entity_info entity_info 
LEFT JOIN ohmt_eai_event_sync_info event_sync_info 
ON        (( 
                              entity_info.source_entity_info_id = event_sync_info.entity_info_id)))
WHERE     ( 
                    entity_info.source_entity_info_id IS NOT NULL)

查询示例
选择*from view where integration\u id=10
此视图的执行计划为该视图中的子查询处理142668行
选择查询视图和集成id=10
这个的执行计划看起来不错,只处理必需的行。

zhte4eai

zhte4eai1#

我认为问题在于以下问题:

SELECT * FROM view WHERE integration_id = 10;

这迫使mysql具体化一个中间表,然后它必须再次查询该中间表以在 WHERE 条款。另一方面,在第二个版本中:

SELECT (QUERY_OF_VIEW with WHERE integration_id = 10)

mysql不必具体化视图本身中的查询以外的任何内容。也就是说,在第二个版本中,mysql只需要在视图中执行查询,而不需要任何后续子查询。

bn31dyow

bn31dyow2#

参考这个文档链接你可以看到,它取决于合并算法是否可以使用它会,但是如果它不适用,那么必须生成新的临时表来查找数据的关系,你也可以看到这个答案,即谈论优化以及何时使用视图和何时不应该使用视图。
如果不能使用合并算法,则必须使用临时表。如果视图包含以下任何构造,则不能使用合并:
聚合函数(sum()、min()、max()、count()等)
不同的
分组依据

限制
联合或联合所有
选择列表中的子查询
仅引用文本值(在本例中,没有基础表)

相关问题