如何在 SQL 服务器上优化我的 sql 查询或数据库?
How to optimize my sql query or database on SQL Server?
有4个table如下:table[T_D ]
约500万行,其他table不到5000行; [T_D ]
有三个主键列:c_id, datetime, a_id
.
4个table之间的关系如下:
table T_D
(
c_id numeric, -- primary key, reference on (M_C.c_id )
datetime datetime, -- primary key
a_id numeric, -- primary key, reference on (M_A.a_id )
data float
)
table M_C
(
c_id numeric, -- primary key
...
)
table M_B
(
b_id numeric, -- primary key
...
)
table M_A
(
a_id numeric, -- primary key
b_id numeric -- reference on (M_B.b_id)
...
)
我正在使用 SQL Server 2008R2,运行 以下 SQL 语句需要几秒钟。我已经尝试了一些解决方案来解决这个问题,但效果不佳,完成 运行ning 仍然需要大约 10 秒。
如何优化此 SQL 查询,并将执行时间降至 200 毫秒以下?
在以下 sql 查询的日期范围内大约有 120 条记录。
要优化的SQL查询:
SELECT
C.c_id, SUM(T.DATA) DATA
FROM
T_D T
LEFT JOIN
M_A A ON A.a_id = T.a_id
LEFT JOIN
M_B B ON B.b_id = A.b_id,
M_C C
WHERE
1=1
AND C.c_id IN (102, 106, 234, 868,319, 347, 215, 162, 297, 372, 630, 280, 347, 572, 321, 239, 252, 724, 233, 39968, 191)
AND T.c_id = C.c_id
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
AND B.b_id IN (100)
GROUP BY
C.c_id
如有任何好的建议,我们将不胜感激!
关系和数据类型似乎没问题。
M_B 是唯一与 T_D 无关的 table。
看看你是否定义了 FK 约束,那么就不需要在查询中加入那些 table。
根据您的可见查询,主要问题是您的查询
不需要在查询中使用M_C C。
如果可能使用 INNER JOIN 或 EXISTS clause.for 来自 M_B 的示例输出并且结果集中不需要 M_A 那么您可以尝试使用 EXISTS 子句。
由于 T_D 有很多记录,所以将谓词放在 T_D 列中,这将改进基数估计。
Notice : T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
SELECT
T.c_id ,SUM(T.DATA) DATA
FROM
T_D T
LEFT JOIN
M_A A
ON A.a_id = T.a_id
LEFT JOIN
M_B B
ON B.b_id = A.b_id
--, M_C C
WHERE
-- 1=1
T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
--AND T.c_id= C.c_id
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
AND B.b_id IN(
100
)
GROUP BY
T.c_id
或者您可以试试
SELECT
T.c_id ,SUM(T.DATA) DATA
FROM
T_D T
where T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
And Exists(
select 1 from
M_A A
inner JOIN
M_B B
ON B.b_id = A.b_id
WHERE
A.a_id = T.a_id
AND B.b_id IN(
100
)
)
GROUP BY
T.c_id
不要在简单连接中使用 M_C C
,因为它不是必需的。
"index not being use."有几个原因
但是我们可以优化查询。
有4个table如下:table[T_D ]
约500万行,其他table不到5000行; [T_D ]
有三个主键列:c_id, datetime, a_id
.
4个table之间的关系如下:
table T_D
(
c_id numeric, -- primary key, reference on (M_C.c_id )
datetime datetime, -- primary key
a_id numeric, -- primary key, reference on (M_A.a_id )
data float
)
table M_C
(
c_id numeric, -- primary key
...
)
table M_B
(
b_id numeric, -- primary key
...
)
table M_A
(
a_id numeric, -- primary key
b_id numeric -- reference on (M_B.b_id)
...
)
我正在使用 SQL Server 2008R2,运行 以下 SQL 语句需要几秒钟。我已经尝试了一些解决方案来解决这个问题,但效果不佳,完成 运行ning 仍然需要大约 10 秒。
如何优化此 SQL 查询,并将执行时间降至 200 毫秒以下? 在以下 sql 查询的日期范围内大约有 120 条记录。
要优化的SQL查询:
SELECT
C.c_id, SUM(T.DATA) DATA
FROM
T_D T
LEFT JOIN
M_A A ON A.a_id = T.a_id
LEFT JOIN
M_B B ON B.b_id = A.b_id,
M_C C
WHERE
1=1
AND C.c_id IN (102, 106, 234, 868,319, 347, 215, 162, 297, 372, 630, 280, 347, 572, 321, 239, 252, 724, 233, 39968, 191)
AND T.c_id = C.c_id
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
AND B.b_id IN (100)
GROUP BY
C.c_id
如有任何好的建议,我们将不胜感激!
关系和数据类型似乎没问题。
M_B 是唯一与 T_D 无关的 table。
看看你是否定义了 FK 约束,那么就不需要在查询中加入那些 table。
根据您的可见查询,主要问题是您的查询
不需要在查询中使用M_C C。
如果可能使用 INNER JOIN 或 EXISTS clause.for 来自 M_B 的示例输出并且结果集中不需要 M_A 那么您可以尝试使用 EXISTS 子句。
由于 T_D 有很多记录,所以将谓词放在 T_D 列中,这将改进基数估计。
Notice : T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
SELECT
T.c_id ,SUM(T.DATA) DATA
FROM
T_D T
LEFT JOIN
M_A A
ON A.a_id = T.a_id
LEFT JOIN
M_B B
ON B.b_id = A.b_id
--, M_C C
WHERE
-- 1=1
T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
--AND T.c_id= C.c_id
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
AND B.b_id IN(
100
)
GROUP BY
T.c_id
或者您可以试试
SELECT
T.c_id ,SUM(T.DATA) DATA
FROM
T_D T
where T.c_id IN (102,106,234,868,319,347,215,162,297,372,630,280,347,572,321,239,252,724,233,39968,191 )
AND T.DATETIME >= '2018-07-01 00:00:00.000'
AND T.DATETIME <= '2018-07-05 00:00:00.000'
And Exists(
select 1 from
M_A A
inner JOIN
M_B B
ON B.b_id = A.b_id
WHERE
A.a_id = T.a_id
AND B.b_id IN(
100
)
)
GROUP BY
T.c_id
不要在简单连接中使用 M_C C
,因为它不是必需的。
"index not being use."有几个原因 但是我们可以优化查询。