在我的SQL Server脚本中,我将一个表连接到一个大表。选择的项目数是否与SQL性能有关?
我的两个选择是:
SELECT
tu.Time,
tu.Machine_id,
AVG(tu.cpu_rate) AS cpu_usage,
AVG(tu.canonical_memory_usage) AS memory_usage,
AVG(tu.cpu_rate) / [dbo].[FnGetCpuInfoWithfailMachineId](tu.machine_id, tu.sampling_start_time) AS cpu_utilization,
AVG(tu.canonical_memory_usage) / dbo.[FnGetMemoryInfoWithfailMachineId](tu.machine_id, tu.sampling_start_time) AS memory_utilization,
[dbo].[FnGetCpuRequestTotalWithfailMachineId](tu.machine_id, tu.sampling_start_time) AS cpu_request_total,
[dbo].[FnGetMemoryRequestTotalWithfailMachineId](tu.machine_id, tu.sampling_start_time) AS memory_request_total,
[dbo].[FnGetPerformanceInfoWithfailMachineId](tu.machine_id, tu.sampling_start_time, AVG(tu.cycles_per_instruction)) AS performance
FROM
[dbo].[failure_host_machine_events] AS h
INNER JOIN
[dbo].[Failed_hosts_task_usage] AS tu ON h.machine_id = tu.machine_id
group by tu.machine_id, tu.time
OR
SELECT
tu.Time,
tu.Machine_id,
[dbo].[FnGetPerformanceInfoWithfailMachineId](tu.machine_id, tu.sampling_start_time, AVG(tu.cycles_per_instruction)) AS performance
FROM
[dbo].[failure_host_machine_events] AS h
INNER JOIN
[dbo].[Failed_hosts_task_usage] AS tu ON h.machine_id = tu.machine_id
group by tu.machine_id, tu.time
非常大的桌子是[dbo].[Failed_hosts_task_usage]
。如果这两个脚本的性能和时间消耗不同,那么有什么想法?或者,因为我加入了这两个表,所以我选择了多少属性
答案 0 :(得分:2)
一般来说,存在差异。两个主要原因:
让我详细说明第二点......假设你有这样的结构:
-- Create a test table...
CREATE TABLE T (
ID int IDENTITY PRIMARY KEY,
NAME nvarchar(255),
FOO int
);
CREATE INDEX THE_INDEX ON T(NAME);
-- Fill it with some data...
WITH DIGIT(N) AS (
SELECT 0
UNION ALL
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
UNION ALL
SELECT 7
UNION ALL
SELECT 8
UNION ALL
SELECT 9
),
NUMBER(N) AS (
SELECT
D4.N * 10000 + D3.N * 1000 + D2.N * 100 + D1.N * 10 + D0.N NUMBER
FROM
DIGIT D0
CROSS JOIN DIGIT D1
CROSS JOIN DIGIT D2
CROSS JOIN DIGIT D3
CROSS JOIN DIGIT D4
)
INSERT INTO T(NAME, FOO)
SELECT N, N FROM NUMBER;
现在,考虑两个几乎相同的查询之间的执行计划差异:
SELECT ID, NAME FROM T WHERE NAME = '50000';
SELECT * FROM T WHERE NAME = '50000';
请注意,第二个查询的工作原理基本上是两倍,因为选择列表中存在FOO!原因是THE_INDEX不是FOO covered,因此对于每个找到的行,数据库必须进行额外的查找才能检索FOO。 (另一方面,ID是PK,因此自动包含在THE_INDEX中。)
结论:努力在SELECT列表中包含仅您实际需要的属性。
这是否会对您的特定案例带来有意义的改进是另一回事......唯一可靠的方法是对代表性的数据量衡量。< / p>
答案 1 :(得分:1)
您的查询在语法上不正确,因为它们应该有group by
。但我仍然认为我理解这个问题。
通常,查询的性能主要取决于访问数据,进行连接和聚合。作为一般规则,属性的数量对性能的影响相对较小。这就是为什么性能优化的大部分工作都集中在选择适当的连接和分组算法上。
尽管如此,有些情况下所选择的内容确实会产生影响。例如:
count(distinct)
比其他聚合更昂贵(for xml path
)。毫无疑问,其他情况也是如此。但在您的情况下,join
和group by
可能会主导性能,您应该集中精力提高速度(如果您关心性能)。