首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用索引优化选择查询

如何用索引优化选择查询
EN

Stack Overflow用户
提问于 2014-02-01 12:52:13
回答 4查看 1.1K关注 0票数 0

我不是专家。我有下面的查询,它包含10个表,MainTable有10个字段,第一个主键和rest外键,9个表称为TableE1 - 10。

下面的查询是在每个表中进行外部连接,我想用索引优化这个查询。

我想知道,怎样才能用索引来优化查询,这个查询在36秒内就能获取10条lacs (100万条)记录,我们能减少多少时间?

MainTable包含10个lacs (100万)记录,表E1-9每个表包含5000条记录。

代码语言:javascript
运行
复制
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
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-01 13:20:08

索引可能不会对此查询有很大帮助,因为查询没有过滤。你正在检索一百万条记录。用于查询的时间中有多少用于检索值,处理查询花费了多少时间?

Server有一个很好的优化器,它将使用复杂的连接算法来执行联接。即使没有索引,查询也很可能运行得很好。

也就是说,使用RecIdDescr对每个"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字节。)问题在于数据库和应用程序之间的层设计,而不是数据库性能。

票数 2
EN

Stack Overflow用户

发布于 2014-02-01 12:57:05

如果表TableE1-TableE9有很多记录,则需要在所有九个表中创建RecID索引。我想您现在有很多记录,但没有索引,因为30秒对于这样简单的查询来说是非常慢的。

票数 0
EN

Stack Overflow用户

发布于 2014-02-01 13:05:48

让我们尝试一下下面的步骤。

  • 在主表上创建具有所有列(E1到E9)的非聚集索引。
  • 在RecID列上的每个子表上创建非群集索引。

让我知道评论/结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21498283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档