Sql 此表的最佳索引&;查询
我有一个sqlite查询,必须尽快运行。查询相当简单,但我不知道索引表以获得最佳性能的最佳方法 该表称为“词典”。定义是:Sql 此表的最佳索引&;查询,sql,sqlite,Sql,Sqlite,我有一个sqlite查询,必须尽快运行。查询相当简单,但我不知道索引表以获得最佳性能的最佳方法 该表称为“词典”。定义是: _id integer primary key word text frequency integer lset integer rset integer 查询是: SELECT word,frequency FROM lexicon WHERE lset>? AND rset<? ORDER BY frequency DESC LIMIT ? 从lexic
_id integer primary key
word text
frequency integer
lset integer
rset integer
查询是:
SELECT word,frequency FROM lexicon WHERE lset>? AND rset<? ORDER BY frequency DESC LIMIT ?
从lexicon WHERE lset>中选择单词、频率?而rset如果SQLite在这方面的行为与其他DBMS类似,那么您将需要在
{lset, rset DESC, frequency DESC}
…按此特定顺序和这些特定的DESC
子句
请查看以获取有关升序/降序索引的更多信息
是的,正如@DanielRenshaw所提到的,您可以在索引末尾包含word
,纯粹是为了允许。这就是所谓的“覆盖”指数
(因为聚类索引已经覆盖了所有字段,所以对于这样一个索引来说,这样做没有任何意义。)这将取决于数据的统计数据
您可以尝试在lset
、rset
和frequency
的每个组合上创建索引,以找到最佳情况,但您必须在表中有真实数据。
-(lset
,rset
,频率
)
-(rset
,lset
,频率
)
-(lset
,frequency
,rset
)
-(rset
,frequency
,lset
)
-(frequency
,lset
,rset
)
-(frequency
,rset
,lset
)
拥有频率
的优势在于,它已经为您的订购依据
和限制
条款做好了准备
但是如果你词典中的每个单词的频率都不一样,那么索引中的第二个和第三个字段就会变得一文不值。(一个说明数据统计为何重要的示例。)
它还关系到哪个字段将限制您最快的记录。如果lset
过滤器将集合缩小为原始大小的0.01%
,请将该过滤器放在索引的第一位
但很有可能,过滤lsety
根本不可能很好地索引。您的查询(名称略有变化):
它将使用索引识别属于(@LeftSide,@RightSide)
范围的行(可能有数千行),然后使用文件排序查找频率最高的(@Num)字
在某些情况下,(frequency DESC,lset,word)
上的索引可能更好(它确实取决于参数值),因此如果您也有该索引,那就更好了。但我无法回答SQLite是否会在每个实例上达到最佳索引的峰值
根据该范围内的行数,它的性能可能会从好到不好。但我认为没有一种简单的方法可以进一步优化这种查询 和往常一样,这要看情况了!在这种情况下,lset
和rset
谓词的选择性至关重要。仅lset>?
就可能返回比rsetGreat问题更多或更少的记录数。我应该提到lset和rset是表示树结构的嵌套集值。因此,lset和rset的所有值都是相互唯一的,并且在1-2*N的范围内完美地分布(其中N是表中的行数)。@Barry:你(也)的意思是,以下内容总是正确的吗?:lset@ypercube:在任何给定的行中,是的。实际上,lset(lset,rset)
组合是唯一的
?值得注意的是,如果Sqlite的行为与其他DBMS类似,添加word
作为索引中的最后一列将使索引覆盖所有必需字段,并避免在其他地方查找该列。如果这个索引将表聚集在一起,这将没有帮助。@DanielRenshaw-同意。查找不在索引中的数据字段类似于添加额外的联接<编码>在索引上加入索引blah JOIN theIndex.PK=theTable.PK上的表
。因此,在索引中包含必要的字段可以消除此开销。(除了在聚集索引中,表是索引。)@Dems我不确定SQLite是否支持这一点,但在“大”DBMS中,您可以混合索引组件的“方向”,所以lset>?及rset@BrankoDimitrijevic-没错。但它仍然没有人们所希望的那么有帮助。例如,假设lset
和rset
都是从0
到99
的整数。lset=0
的索引项下面将有100个rset
项。对于通过搜索条件的每个lset
(平均50%,天真吗?),需要另一个索引查找来检查rset
谓词(1个lset查找,50个rset查找)。它的效果不如lset>x和lset
。特别是当考虑到lset
和rset
可能具有大量合法价值时。非常感谢您的回复。我只是在我的问题中添加了一些原本应该包含的额外信息(对不起)。该表表示树结构,lset/rset是嵌套集对,因此:1。在任何给定的行中,lsetThanks用于查询优化。我现在明白了,rset并不是真正必要的。我按照您的建议更新了查询并为表编制了索引,但仍然不够快。正如你所做的那样,我怀疑它无法进一步优化。好消息:我使用了错误的索引(列的顺序错误),正确排列后,查询速度提高了5-10倍。我想现在它已经足够快了@巴里:我在dba.se上发布了一个相关问题:。请随意关注并在那里发表评论。
SELECT word,frequency
FROM lexicon
WHERE lset > @LeftSide
AND rset < @RightSide
ORDER BY frequency DESC
LIMIT @Num
SELECT word,frequency
FROM lexicon
WHERE lset > @LeftSide --- both `lset` here
AND lset < @RightSide --- and here
ORDER BY frequency DESC
LIMIT @Num
(lset, frequency, word)