【发布时间】:2011-04-24 10:24:39
【问题描述】:
这个问题很大程度上是出于好奇,因为我确实有一个有效的查询(只是比我想要的要长一点)。
我有一个有 400 万行的表。此表上唯一的索引是一个自动递增的 BigInt ID。该查询正在其中一列中查找不同的值,但仅返回 1 天。不幸的是,被评估的 ReportDate 列不是 DateTime 类型,甚至不是 BigInt,而是 YYYYMMDD 格式的 char(8)。所以查询有点慢。
SELECT Category
FROM Reports
where ReportDate = CONVERT(VARCHAR(8), GETDATE(), 112)
GROUP BY Category
请注意,上述语句中的日期转换只是将其转换为 YYYYMMDD 格式进行比较。
我想知道是否有一种方法可以优化此查询,因为我知道我感兴趣的唯一数据位于表的“底部”。我在考虑某种递归 SELECT 函数,它逐渐增长了一个可用于最终查询的临时表。
例如在psuedo-sql中:
N = 128
TemporaryTable = SELECT TOP {N} *
FROM Reports
ORDER BY ID DESC
/* Once we hit a date < Today, we can stop */
if(TemporaryTable does not contain ReportDate < Today)
N = N**2
Repeat Select
/* We now have a smallish table to do our query */
SELECT Category
FROM TemproaryTable
where ReportDate = CONVERT(VARCHAR(8), GETDATE(), 112)
GROUP BY Category
这有意义吗?有这样的可能吗?
这是在 MS SQL Server 2008 上。
【问题讨论】:
-
@Martin 我不是数据所有者,而且我真的很好奇上述是否可行。理想情况下,我们会在报告日期上编制索引(并使其为非字符类型,例如 bigint 或实际日期类型)
-
SELECT MAX(ID) FROM YourTable WHERE ReportDate < CONVERT(VARCHAR(8), GETDATE(), 112)是否会找到感兴趣范围的限制?如果是这样,那么扫描可能会在索引结束时开始反向工作,并且它可以在找到前一天的第一条记录后立即停止。 -
是的,您尝试做的事情是可能的 - 但如果没有
ReportDate上的索引,它永远不会像它可能的那样快......
标签: sql sql-server tsql sql-server-2008 recursion