我不是专家。我有下面的查询,它包含10个表,MainTable有10个字段,第一个主键和rest外键,9个表称为TableE1 - 10。
下面的查询是在每个表中进行外部连接,我想用索引优化这个查询。
我想知道,怎样才能用索引来优化查询,这个查询在36秒内就能获取10条lacs (100万条)记录,我们能减少多少时间?
MainTable包含10个lacs (100万)记录,表E1-9每个表包含5000条记录。
select M.RecID,
M.E1, E1.Descr as E1_D,
M.E2, E2.Descr as E2_D,
M.E3, E3.Descr as E3_D,
M.E4, E4.Descr as E4_D,
M.E5, E5.Descr as E5_D,
M.E6, E6.Descr as E6_D,
M.E7, E7.Descr as E7_D,
M.E8, E8.Descr as E8_D,
M.E9, E9.Descr as E9_D
from ((((((((tableMain M
Left Outer Join TableE1 E1 ON (E1.RecID = M.E1) )
Left Outer Join TableE2 E2 ON (E2.RecID = M.E2) )
Left Outer Join TableE3 E3 ON (E3.RecID = M.E3) )
Left Outer Join TableE4 E4 ON (E4.RecID = M.E4) )
Left Outer Join TableE5 E5 ON (E5.RecID = M.E5) )
Left Outer Join TableE6 E6 ON (E6.RecID = M.E6) )
Left Outer Join TableE7 E7 ON (E7.RecID = M.E7) )
Left Outer Join TableE8 E8 ON (E8.RecID = M.E8) )
Left Outer Join TableE9 E9 ON (E9.RecID = M.E9)
Order by RecID发布于 2014-02-01 13:20:08
索引可能不会对此查询有很大帮助,因为查询没有过滤。你正在检索一百万条记录。用于查询的时间中有多少用于检索值,处理查询花费了多少时间?
Server有一个很好的优化器,它将使用复杂的连接算法来执行联接。即使没有索引,查询也很可能运行得很好。
也就是说,使用RecId和Descr对每个"E“表进行索引可以帮助查询:E1(RecId, Descr)、E2(RecID, Descr)等等。这些都是涵盖指数。对于此查询,Server将使用这些索引,而不必从数据页中读取。只有RecId的索引也不能工作,因为仍然需要在数据页上查找Descr数据。
请注意,这些索引是不必要的(多余的?)如果RecId已经是主键,而Descr是表中的唯一列。
编辑:
这太长了,不能发表评论(我想)。
下面是一些优化这个查询的想法:
首先,是否所有行都是必需的?例如,您可以添加一个top 1000来获得所需的东西吗?只需将行传递回应用程序就会花费大量时间。考虑将它们放入临时表(select into)中。那可能会跑得更快。
第二,order by需要多长时间?尝试在不使用order by的情况下运行查询,以确定这是否占主导地位。
第三,descr字段有多长时间?如果它们很长,那么即使只有几千个数据也可能占主导地位。注这里的“非常长”指的是许多字节,而不是几百个字节。
第四,是descr字段varchar()或char() (或nvarchar()与nchar())。char()和nchar()是非常糟糕的选择,因为它们在结果集中占据了很大的空间。
第五(可能应该是第一位),看看执行计划。您已经给出了一个非常简单的场景,因此我假设执行计划是对第一个表的扫描,每个表都有索引查找。如果计划不像这样,那么可能会有优化的机会。
编辑二:
我再说一遍。将数百兆字节从服务器传输到应用程序需要时间,30'ish秒也不是不合理的。(返回集有10个ids =40个字节加上描述字段,这些字段可能是每条记录的1000字节。)问题在于数据库和应用程序之间的层设计,而不是数据库性能。
发布于 2014-02-01 12:57:05
如果表TableE1-TableE9有很多记录,则需要在所有九个表中创建RecID索引。我想您现在有很多记录,但没有索引,因为30秒对于这样简单的查询来说是非常慢的。
发布于 2014-02-01 13:05:48
让我们尝试一下下面的步骤。
让我知道评论/结果。
https://stackoverflow.com/questions/21498283
复制相似问题