我有两张桌子:
书(身份证,头衔,年龄)----> 100亿行作者(id,book_id,name,born)----> 1000万行
现在,假设我有一本书的通用ID。我需要打印这个页面:
Title: mybook
authors: Tom, Graham, Luis, Clarke, George
那么......最好的方法是什么?
1)像这样的简单连接:
Select book.title, author.name
From book, author
WHERE ( author.book_id = book.id ) AND ( book.id = 342 )
2)为了避免加入,我可以进行2个简单的查询:
Select title FROM book WHERE id = 342
Select name FROM author WHERE book_id = 342
最有效的方式是什么?
答案 0 :(得分:8)
第一个。这只是一次往返。它需要一些处理来将作者行折叠成一个逗号分隔的列表,就像你想要的那样,但这基本上是样板代码。
单独的相关查询是一种坏习惯,会比大多数事情更快地杀死你的表现。
答案 1 :(得分:2)
最好的选择是在您自己的服务器上运行速度测试。根据不同表一起访问和分开的频率,任何一个表都可以更快。
答案 2 :(得分:1)
第一个,特别是如果你有关于author.book_id的索引。如果你有很多作者pr book,那么封闭的索引是最好的,否则非封闭的也会帮助你很多。
答案 3 :(得分:1)
往返最小化和促进理智的执行计划是我的绩效列表中最重要的项目。
如果查询中的字段之间存在静态依赖性,导致优化程序无法使用索引,则将其分解为单独的查询可能会在使用索引和数据集的行数增加时提供巨大的性能提升。对于大多数数据库传输协议,其他结果集等于额外的往返。如果通过WAN定期访问数据,这可能会对性能产生影响。幸运的是,有一些方法可以吃你的蛋糕并吃掉它:
Select title,NULL AS name FROM book WHERE id = 342
UNION ALL
Select NULL,name FROM author WHERE book_id = 342
在您的具体示例中,我会选择#1并发出警告,以考虑如果没有作者存在给定书籍会发生什么。
答案 4 :(得分:0)
我知道它不应该是一个考虑因素,但第一个查询会返回一个像这样的结果集:
title name
-----------------
mybook Tom
mybook Graham
mybook Luis
mybook Clarke
mybook George
而第二对将返回一对结果集,如下所示:
title
-------
mybook
和
name
--------
Tom
Graham
Luis
Clarke
George
所以每种方法都以不同的方式返回数据。在这个简单的例子中,书籍标题的重复并不重要,但是如果不是标题而是返回第一章(比如说),那么效率会降低,因为会有大量的重复数据。因此,虽然第二个可能需要更长的时间在数据库中,但在通过网络发送数据时可能会更快,更有效。
您需要测试实际结果并查看哪一项效果最佳。