我曾在不同的公司工作过,并且我注意到其中有些人更喜欢将视图与所有“亲戚”一起加入表格中。但是随后在应用程序上,我们只需要使用1列。
因此,仅进行简单选择,然后在系统代码上“联接”它们会更快吗?
该系统可以是php,java,asp,也可以是连接到数据库的任何语言。
所以问题是,从服务器端(php,java,asp,ruby,python ...)到数据库的运行速度更快,运行一个查询即可获得我们所需的一切,或者从服务器端运行到数据库并运行一个查询一次只能从一个表中获取列?
我曾在不同的公司工作过,并且我注意到其中有些人更喜欢将视图与所有“亲戚”一起加入表格中。但是随后在应用程序上,我们只需要使用1列。
因此,仅进行简单选择,然后在系统代码上“联接”它们会更快吗?
该系统可以是php,java,asp,也可以是连接到数据库的任何语言。
所以问题是,从服务器端(php,java,asp,ruby,python ...)到数据库的运行速度更快,运行一个查询即可获得我们所需的一切,或者从服务器端运行到数据库并运行一个查询一次只能从一个表中获取列?
Answers:
可以解决您的问题的主题是JOIN DECOMPOSITION。
根据《书》第209页
您可以通过运行多个单表查询而不是多表联接来分解联接,然后在应用程序中执行联接。例如,代替以下单个查询:
SELECT * FROM tag
JOIN tag_post ON tag_post.tag_id = tag.id
JOIN post ON tag_post.post_id = post.id
WHERE tag.tag = 'mysql';
您可以运行以下查询:
SELECT * FROM tag WHERE tag = 'mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);
你到底为什么要这样做?乍一看似乎很浪费,因为您增加了查询数量而没有得到任何回报。但是,这种重组实际上可以带来显着的性能优势:
mysql
已被缓存,则应用程序将跳过第一个查询。如果在缓存中找到ID为123、567或908的帖子,则可以将其从IN()
列表中删除。查询缓存也可以从该策略中受益。如果只有一个表经常更改,则分解联接可以减少缓存失效的次数。IN()
列表而不是联接使MySQL可以对行ID进行排序,并比联接可能获得的查询更优化地检索行。因此,当您缓存和重用早期查询中的大量数据,在多个服务器上分布数据,用IN()
列表替换联接或联接多次引用同一张表时,dos联接在应用程序中的效率更高。
我喜欢第一个要点,因为InnoDB在交叉检查查询缓存时有点笨拙。
Sep 05, 2012
:频繁查询缓存失效的开销是否值得?Jun 07, 2014
:为什么默认情况下从MySQL 5.6开始禁用query_cache_type?至于最后一个要点,我在2013年3月11日写了一篇帖子(描述了嵌套循环算法)(JOIN条件和WHERE条件之间有执行差异吗?)。阅读完之后,您将看到联接分解的效果如何。
至于本书中的所有其他要点,开发人员确实将性能作为底线。有些依赖于外部手段(应用程序外部)来提高性能,例如使用快速磁盘,获得更多的CPU /核心,调整存储引擎以及调整配置文件。其他人会妥协并编写更好的代码。有些人可能会诉诸于在存储过程中对所有商业智能进行编码,但仍未应用联接分解(请参阅反对将逻辑放在数据库层的论点或将逻辑放在数据库层的论点?以及其他文章)。这完全取决于每个开发人员商店的文化和承受能力。
有些人可能会对性能感到满意,因此不再接触代码。其他人根本没有意识到,如果他们尝试加入组合,就会收获很多好处。
对于那些愿意...的开发商
在Postgres的(也可能任何RDBMS程度相近,MySQL的程度较轻),较少的查询几乎都是多快。
在大多数情况下,解析和计划多个查询的开销已经超过了任何可能的收益。
更不用说要在客户端中完成其他工作了,将结果结合起来通常会很慢。RDBMS专门从事这种任务,并且操作基于原始数据类型。不会强制转换text
为中间结果或转换为客户端的本机类型,这甚至可能导致正确(或不正确!)结果的减少。考虑浮点数...
您还将在数据库服务器和客户端之间传输更多数据。对于一手充满价值的手来说,这可以忽略不计,或者产生巨大的变化。
如果多个查询意味着多次往返数据库服务器,则您还将收集网络延迟和事务开销(甚至可能是连接开销)的数倍。大,大损失。
根据您的设置,仅网络延迟可能要比所有其他时间花费几个数量级。
关于SO的相关问题:
对于大型,长期运行的查询可能会有一个转折点,因为事务会在途中收集数据库行上的锁。非常大的查询可能会长时间保留许多锁,这可能会导致与并发查询产生冲突。
returns lots of redundant data for "parent" table
:为什么要返回冗余数据?只返回您需要的数据。