Sql 如何规划没有where子句的查询以防止非索引读取
有件事让我很烦。当我执行查询时,没有任何Sql 如何规划没有where子句的查询以防止非索引读取,sql,firebird,firebird2.5,Sql,Firebird,Firebird2.5,有件事让我很烦。当我执行查询时,没有任何where-子句或orderby-子句,如 select ID from M_TABLE; 读取是非索引的 我需要这个查询这么简单,因为它是在视图的select-语句中使用的。 非索引读取对我来说有一股糟糕性能的臭味。所以我尽量避免使用它们 对于这个非常简单的查询,我只想使用主键对读取进行索引。但当我试图添加这样的计划声明时 select ID from M_TABLE t plan (t index (PK_M_TABLE)); 错误消息
where
-子句或orderby
-子句,如
select ID
from M_TABLE;
读取是非索引的
我需要这个查询这么简单,因为它是在视图的select
-语句中使用的。
非索引读取对我来说有一股糟糕性能的臭味。所以我尽量避免使用它们
对于这个非常简单的查询,我只想使用主键对读取进行索引。但当我试图添加这样的计划声明时
select ID
from M_TABLE t
plan (t index (PK_M_TABLE));
错误消息
无法在指定的计划中使用索引
索引PK_M_表不能在指定的计划中使用
他们回来了
如何强制将读取内容编入索引?我是否在计划语句中拼写错误?我看了一下,但没有看到语法错误,我认为这实际上不是语法错误
DDL:
CREATE TABLE M_TABLE (
ID INTEGER NOT NULL);
ALTER TABLE M_TABLE ADD CONSTRAINT PK_M_TABLE PRIMARY KEY (ID);
注意:
我已经在下面发布了一个可能的解决方法。如果你认为这是唯一可能的解决办法,请随意投票赞成。但是,如果有其他解决方案,请将其作为其他答案发布。强制对读取进行索引的一种可能性是在相关索引字段上添加一个
order by
-子句:
select ID
from M_TABLE
order by ID;
因此,计划语句
plan(M_TABLE order PK_M_TABLE)
在内部使用。如果您没有指定使用索引的where子句(或order by),那么plan natural很可能是最好的计划,尤其是如果您计划读取整个表
Firebird没有聚集索引,因此即使对于索引读取,它最终也必须从表数据页本身读取。索引读取本身可能更快,但从数据页随机读取数据可能比按数据页顺序读取数据更昂贵。我所知道的唯一例外是,如果你有大量的更新和删除,会产生大量的垃圾和反版本
据我所知,你对这是一种观点的担心是没有根据的。在另一个查询中使用视图时,Firebird将内联视图,并对整个查询进行优化。在视图中应用order by(如答案中所示)实际上可能会在非平凡查询中使用视图时损害性能