temp表与内部连接中的子查询

d8tt03nd  于 2021-06-25  发布在  Mysql
关注(0)|答案(3)|浏览(334)

两个sql返回相同的结果。第一个我的联接在子查询上,第二个我的最后一个查询是一个联接,它带有一个我以前创建/填充它们的临时联接

SELECT COUNT(*) totalCollegiates, SUM(getFee(c.collegiate_id, dateS)) totalMoney
FROM collegiates c
LEFT JOIN (
    SELECT collegiate_id FROM collegiateRemittances r
    INNER JOIN remittances r1 USING(remittance_id)
    WHERE r1.type_id = 1 AND r1.name = remesa   
) hasRemittance ON hasRemittance.collegiate_id = c.collegiate_id
WHERE hasRemittance.collegiate_id IS NULL AND c.typePayment = 1 AND c.active = 1 AND c.exentFee = 0 AND c.approvedBoard = 1 AND IF(notCollegiate, c.collegiate_id NOT IN (notCollegiate), '1=1');

DROP TEMPORARY TABLE IF EXISTS hasRemittance;

CREATE TEMPORARY TABLE hasRemittance
    SELECT collegiate_id FROM collegiateRemittances r
    INNER JOIN remittances r1 USING(remittance_id)
    WHERE r1.type_id = 1 AND r1.name = remesa;

SELECT COUNT(*) totalCollegiates, SUM(getFee(c.collegiate_id, dateS)) totalMoney
FROM collegiates c
LEFT JOIN hasRemittance ON hasRemittance.collegiate_id = c.collegiate_id
WHERE hasRemittance.collegiate_id IS NULL AND c.typePayment = 1 AND c.active = 1 AND c.exentFee = 0 AND c.approvedBoard = 1 AND IF(notCollegiate, c.collegiate_id NOT IN (notCollegiate), '1=1');

几千张唱片哪一张性能更好?

tjrkku2a

tjrkku2a1#

这要看情况了。你必须测试每个选项的性能。在我的网站上,我有两个表格,上面有文章和评论。结果发现,对每篇文章调用20次comment counts比使用单个联合查询更快。mysql(和其他dbs一样)缓存查询,所以小的简单查询可以运行得非常快。

q9yhzks0

q9yhzks02#

我没有看到你把这个问题标记为mysql,所以我最初问的是oracle。下面是我对mysql的看法。
mysql对于临时表内存或磁盘有两种选择。对于磁盘,可以使用myisam-非事务性和innodb事务性。当然,对于非事务性存储类型,您可以期望获得更好的性能。
另外,你需要弄清楚你处理的结果集有多大。对于小结果集,“内存”选项会更快对于大结果集,“磁盘”选项会更快。
最后,正如我最初的回答一样,你需要弄清楚什么样的性能足够好,并选择最具描述性和易于阅读的选项。
Oracle
这取决于你要处理什么样的临时表。
您可以使用基于会话的临时表—数据保留到注销,或者基于事务—数据保留到提交。除此之外,它们可以支持事务日志记录,也可以不支持事务日志记录。根据配置,您可以从临时表中获得更好的性能。
因为世界上的一切表现都是相对热的。最有可能的是,对于几千条记录来说,这两个查询之间不会有显著差异。在这种情况下,我会去不是为了最好的表现,而是为了最容易阅读和理解的一个。

h7appiyu

h7appiyu3#

这两个公式是相同的,只是您的显式temp表版本是3个sql语句,而不是1个。也就是说,往返于服务器的开销使其速度变慢。但是。。。
因为隐式temp表在 LEFT JOIN ,该子查询可以通过以下两种方式之一进行计算。。。
mysql的旧版本被“转储”并重新评估。因此缓慢。
较新版本会自动创建索引。所以很快。
同时,可以通过添加适当的索引来加快显式temp表的版本。会的 PRIMARY KEY(collegiate_id) . 如果有可能的话 INNER JOIN 制作DUP,然后说 SELECT DISTINCT .
对于“几千”行,通常不需要担心性能。
甲骨文有无数的选择。mysql很少,默认的是(通常)最好的。所以忽略讨论了mysql中可以使用的各种选项的答案。
有一些问题

AND  IF(notCollegiate,
        c.collegiate_id NOT IN (notCollegiate),
        '1=1')

我不知道是哪张table notCollegiate 是在。 notCollegiate 不能是列表,为什么要使用 IN ? 而是简单地使用 != . 最后, '1=1' 是3个字符的字符串;你真的想要吗?
性能(任一版本) remittances 需要 INDEX(type_id, name, remittance_id)remittance_id 特别是最后一个。 collegiateRemittances 需要 INDEX(remittance_id) (除非是pk)。 collegiates 需要 INDEX(typePayment, active, exentFee , approvedBoard) 以任何顺序。
一句话:更关心的是索引,而不是如何构造查询。
哎哟。又一条皱纹。是什么 getFee() ? 如果它是一个存储函数,也许我们需要担心优化它??什么是约会?

相关问题