加入具有不同索引的列

时间:2013-06-26 08:00:25

标签: sql sql-server sql-server-2008

我正在使用查询连接列,其中一个具有聚簇索引,另一个具有非聚集索引。该查询需要很长时间。这是我使用不同类型索引的原因吗?

SELECT @NoOfOldBills = COUNT(*)
FROM Billing_Detail D, Meter_Info m, Meter_Reading mr
WHERE D.Meter_Reading_ID = mr.id
     AND m.id = mr.Meter_Info_ID
     AND m.id = @Meter_Info_ID
     AND BillType = 'Meter'

IF (@NoOfOldBills > 0) BEGIN

     SELECT TOP 1 @PReadingDate = Bill_Date
     FROM Billing_Detail D, Meter_Info m, Meter_Reading mr
     WHERE D.Meter_Reading_ID = mr.id
          AND m.id = mr.Meter_Info_ID
          AND m.id = @Meter_Info_ID
          AND billtype = 'Meter'
     ORDER BY Bill_Date DESC

END

3 个答案:

答案 0 :(得分:1)

在不了解更多细节和背景的情况下,提出建议很棘手 - 但看起来您正试图找出最旧法案的日期。您可以将这两个查询重写为一个,这将显着提高性能(假设有一些旧账单)。

我会建议这样的事情 - 除了可能表现更好之外,还有点容易阅读!

SELECT count(d.*) NoOfOldBills, MAX(d.Billing_Date) OldestBillingDate FROM Billing_Detail d
  INNER JOIN Meter_Reading mr ON  mr.id=d.Meter_Reading_ID
  INNER JOIN Meter_Info m ON m.Id=mr.Meter_Info_ID
WHERE
  m.id = @Meter_Info_ID AND billtype = 'Meter'

答案 1 :(得分:0)

好的,这里有很多东西。首先,你有相关的指数(或与它们相关的指数)。每个表上应该有一个聚簇索引 - 如果表没有聚簇索引,非聚簇索引用于标识行,则非聚簇索引不能有效工作。

您的索引是否只涵盖一列? SQL Server使用索引,该索引的列顺序非常重要。索引的最左列(通常)应该是具有最大常数的列(将数据划分为最小量)。任一索引都覆盖查询中引用的所有列(这称为覆盖index(Google以获取更多信息)。

一般来说,索引应该是宽的,如果SQL Server在col1,col2,col3,col4上有索引,而另一个在col1,col2上,则后者是冗余的,因为来自第二个索引的信息完全包含在第一个和SQL中服务器理解这一点。

您的统计数据是最新的吗?如果统计信息不是最新的,SQL Server可以/将选择错误的执行计划。查询分析器为计划执行显示什么(SSMS查询|显示执行计划)?

答案 2 :(得分:0)

原因不是因为您有不同类型的指数。既然你说你在所有主键上都有聚簇索引,你应该没问题。要支持此查询,您还需要一个在BillType和Bill_Date上有两列的索引来缩短时间。

希望他们在同一张桌子上。否则,您可能需要一些索引来最终创建一个具有两列的索引。