重复查询大表的最快方法



我有一个有5000万条记录的表,但它是一个紧凑的结构(id,int1,int 1,int 2,int 3)。所有相关指标均已落实。

对于每个用户交互,我需要查询大约50次。使用针对数据库服务器的常规查询,这大约需要5秒钟的时间。所有的查询都是简单的选择。

我的问题是:我能做些什么来加快速度,甚至花更多的内存?查询的Locate方法不够灵活,直接在查询中使用筛选器的速度较慢。

我正在运行的主要查询是

select knowledge_id, knowledge_family_id, tag_level, tag_order, 
  total_title_direct_words, total_title_parenthesis_words from knowledge_tags 
  where dictionary_word_id = XX order by tag_level, tag_order

有人能提出一个策略吗?TVirtualTable会提高速度吗?

考虑到将整个表加载到内存中不是问题,我建议:

  1. 执行查询以选择所有记录
  2. 在数据集上行走一次以将记录复制到TObjectList<TMyRecord>,其中TMyRecord是可以包含数据集记录的所有字段的类;使其成为对象列表中数据集的副本
  3. 如果可能,对列表进行排序(或按正确顺序选择),以便在需要时运行二进制搜索
  4. 释放数据集并仅处理列表

在这种情况下,您将避免所有数据集开销,每次搜索都会更快。

TMyRecord的一个例子是:

interface
type
  TMyRecord = class
  private
    FId: Integer;
    FCol1: Integer;
    FCol2: Integer;
    FCol3: Integer;
    FCol4: Integer;
  public
    constructor Create(aId, aCol1, aCol2, aCol3, aCol4: Integer);
    property Id: Integer read FId write FId;
    property Col1: Integer read FCol1 write FCol1;
    property Col2: Integer read FCol2 write FCol2;
    property Col3: Integer read FCol3 write FCol3;
    property Col4: Integer read FCol4 write FCol4;
  end;
implementation
constructor TMyRecord.Create(aId, aCol1, aCol2, aCol3, aCol4: Integer);
begin
  FId := aId;
  FCol1 := aCol1;
  FCol2 := aCol2;
  FCol3 := aCol3;
  FCol4 := aCol4;
end;

我认为在TClientDataSet中加载整个数据并使用FINDKEY查找这些记录会快得多。

要使用FindKey(),您必须这样定义索引:

Cds.IndexDefs.ADD('IDX1', 'FieldA;FieldB',[]);
Cds.IndexName := 'IDX1';
if Cds.FindKey([A,B]) then begin
  //Do something
end;

您还可以创建多个索引,并随时使用它:

Cds.IndexDefs.ADD('IDX1', 'FieldA;FieldB',[]);
Cds.IndexDefs.ADD('IDX2', 'FieldD;FieldB',[]);
Cds.IndexDefs.ADD('IDX3', 'FieldA;FieldC',[]);  
if SeekAB then 
  Cds.IndexName := 'IDX1'
else if SeekDB then 
  Cds.IndexName := 'IDX2'
else 
  Cds.IndexName := 'IDX3';

相关内容

  • 没有找到相关文章

最新更新