2016-07-25 125 views
0

我被给了这个查询来更新报告,并且在我的计算机上运行需要很长时间。什么是MySQL中的“point-in-select”?

select 
c.category_type, t.categoryid, t.date, t.clicks 
from transactions t 
join category c 
    on c.category_id = t.categoryid 

我问DBA是否有与查询的任何问题,而DBA优化以这种方式查询:

select 
    (select category_type 
    from category c where c.category_id = t.categoryid) category_type, 
    categoryid, 
    date, clicks 
from transactions t 

他所描述的第一子查询的“点式选”。我从来没有听说过这个。有人可以解释这个概念吗?

+1

而且第二个查询有更好的表现吗?我认为他们应该非常相似。此外,我从来没有听说过“点选”,Google也没有提到任何事情。 –

+2

你有提供两种'EXPLAIN'的机会吗?第二个查询实际上看起来更糟。 – zerkms

+0

这是[相关子查询](https://en.wikipedia.org/wiki/Correlated_subquery)。请注意,他的短语没有出现在维基链接中,我从来没有听说过它。令我惊讶的是,这使您在RDBMS的现代版本上显着提高了性能。 –

回答

2

我要指出,这两个查询是不一样的,除非符合下列条件:

  • transactions.categoryid总是出现在category
  • category没有重复的值category_id

实际上,这些都是真实的(在大多数数据库中)。第一个查询应该是使用left join版本更接近等价:

select c.category_type, t.categoryid, t.date, t.clicks 
from transactions t left join 
    category c 
    on c.category_id = t.categoryid; 

还是不完全一样,但更多的类似。

最后,这两个版本都应该使用category(category_id)上的索引,我期望MySQL中的性能非常类似。

0

您的DBA的查询与其他人指出的查询和afaik非标准SQL不一样。仅仅因为它的简单性,你就更加可取。

重新编写性能查询通常不是有利的。它有时可以提供帮助,但DBMS应该等效地执行逻辑上等效的查询。不这样做是查询计划者中的一个缺陷。

性能问题通常是物理设计的一个功能。在你的情况下,我会寻找categorytransactions表中包含categoryid作为第一列的索引。如果两者都不存在,那么您的加入是O(mn),因为必须针对每个事务行扫描category表。

不是MySQL用户,我只能建议您获取查询计划器输出并查找索引机会。