2

关于连接两个表与使用 2 个单独查询的二分法,我有一个简单的问题。

我希望找到一个现有的问题,但我的搜索并没有产生太多结果(大多数问题都是针对更复杂的问题)。

例如,考虑具有非常简单架构的两个表 A 和 X:

Table A   +-------------+-------------+-------------+
          | Column A (*)| Column X(FK)| Column C    |
          +-------------+-------------+-------------+

Table X   +-------------+-------------+-------------+
          | Column X (*)| Column Y    | Column Z    |
          +-------------+-------------+-------------+

其中 A 列和 X 列是标识列和主键 (bigint)。表 A 和表 X 之间还存在列 X 的现有外键关系。

我的问题是,假设两个表都足够大(仅说 500K 行),我是否会从使用单个查询(参见下面的 Linq2Sql 伪代码)或使用两个单独的查询中获得更多的性能?

选项1:

long aValue = 107;
DataContext dc = new DataContext();
var items = (from a in dc.TableA
             join x in dc.TableX
             on a.X equals x.X
             where a.A == aValue
             select new { a, x });

选项 2:

  • 假设我编写了一个 SP 串行执行 2 个单独的选择语句。

为了进一步量化问题,您可以假设对于 A 的每个值,只有几 (0-5) 行将从表 Y 中连接,因此连接中返回的表 A 数据的重复并不重要。

我要求严格从数据库服务器影响的角度来看。因此,忽略任何客户端考虑因素(例如往返网络延迟、L2S 查询构建和数据编组成本等),我的问题是:

  1. 哪个选项将花费更少的时间在数据库服务器上进行计算?

  2. 哪个选项需要更少的内存来评估结果?

  3. 如果有最佳实践,通常首选哪个选项?

对不起,如果这听起来太初级,但任何见解将不胜感激。

谢谢,-K。

4

2 回答 2

2

简短的回答:相信优化器。

针对索引良好的表的单个查询(尤其是使用简单连接)将比编写一组串行 SQL 语句更有效。我不是 LINQ 方面的专家,所以我不确定您将使用伪代码返回哪些列,但如果这些表在适当的硬件上正确索引,那么您会没事的。

于 2012-11-16T23:39:45.723 回答
1

好吧,根据我在繁忙的数据库中的经验,运行两个没有连接的查询总是比一个有连接的查询要好。

这两种方法之间总会有一个区别:当您加入时,SQL必须以某种方式匹配行(当预测返回的行数较少时,可能使用嵌套循环)。当工作量或结果集很大时,它开始变得重要。

如果您不希望您的数据库成为瓶颈,并且此连接以某种方式简化了开发,那么请继续使用它。


为了在更大的表上为您提供任何数字,我尝试了两种针对我管理的数据库上的父表和子表的方法。它们分别有 150k 行和 3000k 行。SQL 打印这些统计信息:

加入查询

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 7 ms.
Table 'child'. Scan count 1, logical reads 324, physical reads 0, read-ahead reads 0.
Table 'parent'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 70 ms.

单独选择

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 'parent'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1 row(s) affected)
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 'child'. Scan count 1, logical reads 324, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 1 ms.

(表有适当的索引;表名已更改)

于 2012-11-16T23:58:07.027 回答