简体   繁体   English

MySQL View的性能比底层查询的性能差

[英]Performance of MySQL View is Worse than that of Underlying Query

I have a MySQL view defined using the below ( JOIN statements omitted for brevity). 我使用下面定义的MySQL视图(为简洁起见省略了JOIN语句)。

CREATE VIEW vw_example AS 
SELECT a, b, c FROM x, y, z

Over many repetitions SELECT a, b, c FROM x, y, z is 5 times faster than SELECT a, b, c FROM vw_example . 经过多次重复, SELECT a, b, c FROM x, y, zSELECT a, b, c FROM vw_example快5倍。

I'm looking to understand why this is and how to bring the SELECT FROM vw_example performance inline with the underlying SELECT FROM x, y, z . 我想了解为什么会这样,以及如何使SELECT FROM vw_example性能与底层SELECT FROM x, y, z内联。

Although you don't show a DISTINCT in your example query, I recently discovered this to be the one single distinguishing factor in the performance difference between a query run directly, vs run as a view. 虽然您没有在示例查询中显示DISTINCT,但我最近发现这是直接查询运行与作为视图运行之间性能差异的唯一区别因素。

With SELECT DISTINCT on my query doing an INNER JOIN on a 726,000 row table and a 303,000 row table, joining ON 3 columns for which each table has an index, the direct query is running about 0.15-0.16s duration. 使用SELECT DISTINCT对我的查询在726,000行表和303,000行表上执行INNER JOIN,连接ON 3列,每个表都有一个索引,直接查询运行大约0.15-0.16s持续时间。 When I use the VIEW created with the same query (and nothing else) the duration is about 142-145s or about 10^3 times as long. 当我使用使用相同查询创建的VIEW(没有别的)时,持续时间大约为142-145s或大约10 ^ 3倍。

Removing DISTINCT reduced both the query itself and the view it is based on to 0.016s--there is virtually no difference at all. 删除DISTINCT减少了查询本身和它基于0.016秒的视图 - 几乎没有任何区别。

I can't help with understanding why--only with recognizing one cause in one particular case. 我无法理解为什么 - 只有在一个特定情况下认识到一个原因。

I am not sure, but maybe mysql is using tmp tables much better for one of the queries. 我不确定,但是对于其中一个查询,mysql可能更好地使用tmp表。 Please adjust these settings and then try again: 请调整这些设置,然后重试:

tmp_table_size   100M
max_heap_table_size 128M
query_cache_limit  350M
query_cache_size 300M

Use set global before them so that you can set them on the fly, hope this might just work. 在它们之前使用set global ,以便您可以动态设置它们,希望这可能正常工作。 If not then you might need to look into re writing the query. 如果没有,那么您可能需要重新编写查询。

It's hard to be precise - the best way to investigate is to run EXPLAIN on both flavours of the query . 这很难准确 - 调查的最佳方法是在查询的两种风格上运行EXPLAIN

However, my suspicion is that the query cache is at the heart of this - re-running the same query will seed the query cache, and unless the underlying data changes, or the cache gets flushed, you're likely to benefit from the caching. 但是,我怀疑查询缓存是其核心 - 重新运行相同的查询将为查询缓存设定种子,除非底层数据发生更改,或者缓存被刷新,否则您可能会受益于缓存。

You'd expect to get that benefit when hitting the view, too, but caching is non-deterministic, and my guess is that, somehow, your queries against the view aren't benefiting from the caching. 你也希望在点击视图时获得这样的好处,但是缓存是非确定性的,我的猜测是,不管怎么说,你对视图的查询都没有从缓存中受益。

If the EXPLAINs are identical, that would be the best explanation... 如果EXPLAINs相同,那将是最好的解释......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM