2012-10-17 46 views
2

数据库大师曾建议重构查询:这是否优化总是工作

SELECT * FROM MyTable 
WHERE UnIndexedDate 
BETWEEN '2012-08-01' AND '2012-09-01' 

SELECT * FROM MyTable 
WHERE IndexedID 
BETWEEN (SELECT MIN(IndexedID) FROM MyTable WHERE UnIndexedDate BETWEEN '2012-08-01' AND '2012-08-30') 
AND (SELECT MAX(IndexedID) FROM MyTable WHERE UnIndexedDate BETWEEN '2012-08-01' AND '2012-08-30') 

注意到,该表不被索引的UnIndexedDate列,但被收录在IndexedID列。该表中有数百万条记录。

它显然确实提高了查询的速度,我怀疑这是因为子查询只会执行一次,甚至可能在某种程度上效率更高,因为它们涉及索引字段。

我的问题是,这是否适用于大多数数据库或只是在这里SQL2000之一。

增加:顺便说一句IndexedID是数字,唯一并严格增加。

+2

除非'IndexedID'和'UnIndexedDate'相关,否则它会改变结果。你的表格定义是什么? 'UnIndexedDate'是否包含在'IndexedID'的辅助列中?如果没有,我不会看到重写会如何改进,因为建立“MIN”和“MAX”要么需要2次扫描,要么可能有很多查找。 –

+1

你能提供两个版本的执行计划吗? – Thilo

+1

@MartinSmith:+1只有当IndexedId的排序方式与UnindexedDate完全相同时,它才会起作用。 (如果UnindexedDate真的没有索引,我不会看到这样做会更快。似乎它应该在IndexedId的复合索引中,以使其工作)。 – Thilo

回答

0

只有当未索引的日期列与索引ID列相连时,您的优化才有效;这是一个设计假设,而不是它运行的平台。换句话说,这听起来像未索引日期与索引ID相关联,因为ID是在插入时插入的自动编号,并且未索引日期是插入时间。在这种狭隘的情况下,@马丁史密斯的评论将成立;如果未索引日期列和索引列没有相关性,结果可能会有所不同。

没有看执行计划,我敢打赌,你会看到表上的两个扫描来检索ID(一个非常窄小的数据集),然后索引试图返回实际的行。只要假定的关系成立,它就会工作。但是,如果某人更新为日期列(并且打破日期和ID之间的关系),则结果将不再准确,因为MIN或MAX ID值可能不在该范围内。

+0

日期列类型 - 从某种意义上说,它们都相当一致地增加。日期实际上是交易发生的日期,而不是它插入表格的日期,但足够接近聪明的数据库。 – OldCurmudgeon