sud*_*.ie 93 mysql postgresql performance join query-performance
我一直在为不同的公司工作,我注意到他们中的一些人更喜欢拥有将所有“亲戚”加入表格的视图。但是在应用程序中,有时我们只需要使用 1 列。
那么只进行简单的选择,然后将它们“加入”到系统代码中会更快吗?
该系统可以是 php、java、asp 或任何连接到数据库的语言。
所以问题是,从服务器端(php、java、asp、ruby、python...)到数据库并运行一个查询来获取我们需要的一切或从服务器端到数据库并运行哪个更快?一次只从一个表中获取列的查询?
Rol*_*DBA 88
什么可以解决您的问题是主题 JOIN DECOMPOSITION。

您可以通过运行多个单表查询而不是多表连接来分解连接,然后在应用程序中执行连接。例如,而不是这个单一的查询:
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';
Run Code Online (Sandbox Code Playgroud)
您可以运行以下查询:
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);
Run Code Online (Sandbox Code Playgroud)
你到底为什么要这样做?乍一看,这看起来很浪费,因为您增加了查询次数而没有得到任何回报。但是,这种重组实际上可以带来显着的性能优势:
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/内核、调整存储引擎和调整配置文件。其他人会屈服并编写更好的代码。有些人可能会在存储过程中对所有商业智能进行编码,但仍然没有应用连接分解(请参阅反对或支持将应用程序逻辑放入数据库层的论据是什么?以及其他帖子)。这完全取决于每个开发商商店的文化和容忍度。
有些人可能对性能感到满意,不再接触代码。其他人根本没有意识到如果他们尝试加入组合,可以获得很大的好处。
对于那些愿意...
Erw*_*ter 39
在Postgres的(也可能任何RDBMS程度相近,MySQL的程度较轻),较少的查询几乎都是多快。
在大多数情况下,解析和规划多个查询的开销已经超过了任何可能的收益。
更不用说在客户端完成额外的工作,结合结果,这通常要慢得多。RDBMS 专门从事这种任务,操作基于原始数据类型。无需text为中间结果进行转换或返回转换或转换为客户端的本机类型,这甚至可能导致不太正确(或不正确!)的结果。想想浮点数...
您还可以在数据库服务器和客户端之间传输更多数据。这对于一手充满价值的手来说可能可以忽略不计,或者产生巨大的差异。
如果多次查询意味着多次往返数据库服务器,您还需要多次收集网络延迟和事务开销,甚至可能是连接开销。大,大损失。
根据您的设置,单独的网络延迟可能比其他所有延迟要长几个数量级。
关于SO的相关问题:
对于非常大的、长时间运行的查询,可能会有一个转折点,因为事务会在途中收集 DB 行上的锁。非常大的查询可能会在很长一段时间内持有许多锁,这可能会导致并发查询的摩擦。
| 归档时间: |
|
| 查看次数: |
132146 次 |
| 最近记录: |