0

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

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
4

3 回答 3

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'
于 2013-06-26T08:22:43.433 回答
0

好的,这里有很多东西。首先,您的索引是否相关(或尽可能相关)。每个表上都应该有一个聚集索引 - 如果表没有非聚集索引用于标识行的聚集索引,则非聚集索引无法有效工作。

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

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

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

于 2013-06-26T08:13:55.897 回答
0

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

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

于 2013-06-26T14:23:59.870 回答