建索引没有?
用TOP取部分记录

解决方案 »

  1.   


    这么多啊!
    试这个看看行不行?
    $cha="select * from table where(name=$name)and(email=$email);
      

  2.   

    好恐怖呀。这么多条记录。
    无论怎么优化,查询时还是要遍历每一条记录的。就看你算法怎么优化了。
    按照你的思路,字段email中的值应该是唯一的,所以查询要首先用email去判断。
      

  3.   

    索引建了!是sybase数据库!用直接查询我试过了,要将近一分钟左右才出来!有没有其他好的办法呀!但是实际情况中没有唯一的字段呀!
      

  4.   

    “anybody1(随便编一个) 建立一个索引表然后写一个哈西算法进行过滤
    把那些过滤后的结果直接根据一个数据库里的字段提取呗
    比如用户名啊,ip啊什么的显示这条记录你所想要的字段的数据呗 ”
    能具体说一下吗?
      

  5.   

    就是数据库只是用来读数据把需要他实现的查询功能放在外面实现
    我个人认为好一点的算法是哈西算法,就是写一个哈西算法的脚本去读那个索引表把你想要的那些记录读出来
    关于哈西算法的实现,我只有delphi的不过原理是一样的你可以看看:(php好久没用了*^*)
    {$define debug}
    unit HashTable;interfaceuses Windows, SysUtils;const
      LeafSize = 256;
      BucketSize = 8;type
      TLinkedItem = class
      private
        Value: DWORD;
        Data: DWORD;
        Next: TLinkedItem;
        constructor Create(FValue,FData: DWORD; FNext: TLinkedItem);
        destructor Destroy; override;
      end;  THashTable = class; // forward
      TTraverseProc = procedure (UserData,UserProc: Pointer;
        Value,Data: DWORD; var Done: Boolean) of object;  TTreeItem = class
      private
        Owner: THashTable;
        Level: integer;
        Filled: integer;
        Items: array[0..LeafSize-1] of TObject;
        constructor Create(AOwner: THashTable);
        destructor Destroy; override;
        function ROR(Value: DWORD): DWORD;
        function RORN(Value: DWORD; Level: integer): DWORD;
        procedure AddDown(Value,Data,Hash: DWORD);
        procedure Delete(Value,Hash: DWORD);
        function Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
        function Traverse(UserData,UserProc: Pointer; TraverseProc: TTraverseProc): Boolean;
      end;  THashTable = class
      private
        Root: TTreeItem;
      protected
        function HashValue(Value: DWORD): DWORD; virtual; abstract;
        procedure DestroyItem(var Value,Data: DWORD); virtual; abstract;
        function CompareValue(Value1,Value2: DWORD): Boolean; virtual; abstract;
        procedure AddDown(Value,Data,Hash: DWORD);
        procedure Delete(Value,Hash: DWORD);
        function Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
        procedure Traverse(UserData,UserProc: Pointer; TraverseProc: TTraverseProc);
      public
        constructor Create; virtual;
        destructor Destroy; override;
      end;  TStrHashTraverseProc = procedure (UserData: Pointer; const Value: string;
        Data: TObject; var Done: Boolean);
      TStrHashTraverseMeth = procedure (UserData: Pointer; const Value: string;
        Data: TObject; var Done: Boolean) of object;  TStringHashTable = class(THashTable)
      private
        FCaseSensitive: Boolean;
        FAutoFreeObjects: Boolean;
      protected
        function HashValue(Value: DWORD): DWORD; override;
        procedure DestroyItem(var Value,Data: DWORD); override;
        function CompareValue(Value1,Value2: DWORD): Boolean; override;
        function HashStr(const S: string): DWORD;
        procedure TraverseProc(UserData,UserProc: Pointer;
          Value,Data: DWORD; var Done: Boolean);
        procedure TraverseMeth(UserData,UserProc: Pointer;
          Value,Data: DWORD; var Done: Boolean);
      public
        constructor Create; override;
        procedure Add(const S: string; Data: TObject);
        procedure Delete(const S: string);
        function Find(const S: string; var Data: TObject): Boolean;
        procedure Traverse(UserData: Pointer; UserProc: TStrHashTraverseProc); overload;
        procedure Traverse(UserData: Pointer; UserProc: TStrHashTraverseMeth); overload;
        property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive default False;
        property AutoFreeObjects: Boolean read FAutoFreeObjects write FAutoFreeObjects default False;
      end;function CalcStrCRC32(const S: string): DWORD;
      
    {$ifdef debug}
    type
      TLenStat = array[1..BucketSize] of integer;procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer;
      var LenStat: TLenStat);
    {$endif}implementation{$ifdef debug}
    procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer;
      var LenStat: TLenStat);  procedure TreeStat(ht: TTreeItem);
      var j,i: integer;
          LinkedItem: TLinkedItem;
      begin
        Inc(PeakCnt);
        if ht.Level+1 > MaxLevel then
          MaxLevel:=ht.Level+1;
        for j:=0 to LeafSize-1 do
          if ht.Items[j] <> nil then begin
            Inc(FillCnt);
            if ht.Items[j] is TTreeItem then begin
              TreeStat(TTreeItem(ht.Items[j]));
            end else begin
              i:=0;
              LinkedItem:=TLinkedItem(ht.Items[j]);
              while LinkedItem <> nil do begin
                Inc(i);
                LinkedItem:=LinkedItem.Next;
              end;
              LenStat[i]:=LenStat[i]+1;
            end;
          end else
            Inc(EmptyCnt);
      end;
    begin
      if ht.Root <> nil then
        TreeStat(ht.Root);
    end;
    {$endif}{ TTreeItem }procedure TTreeItem.AddDown(Value, Data, Hash: DWORD);
    var i,j: integer;
        TreeItem: TTreeItem;
        LinkedItem: TLinkedItem;
    begin
      i:=Hash and $FF;
      if Items[i] = nil then begin
        Items[i]:=TLinkedItem.Create(Value,Data,nil);
        Inc(Filled);
      end else if Items[i] is TTreeItem then begin
        TTreeItem(Items[i]).AddDown(Value,Data,ROR(Hash));
      end else begin
        j:=0;
        LinkedItem:=TLinkedItem(Items[i]);
        while LinkedItem <> nil do begin
          if Owner.CompareValue(LinkedItem.Value,Value) then begin
            // found
            LinkedItem.Data:=Data;
            Exit;
          end;
          LinkedItem:=LinkedItem.Next;
          Inc(j)
        end;
        if j >= BucketSize then begin
          // full
          TreeItem:=TTreeItem.Create(Owner);
          TreeItem.Level:=Level+1;
          LinkedItem:=TLinkedItem(Items[i]);
          while LinkedItem <> nil do begin
            TreeItem.AddDown(LinkedItem.Value, LinkedItem.Data,
                            RORN(Owner.HashValue(LinkedItem.Value), Level+1));
            LinkedItem:=LinkedItem.Next;
          end;
          TreeItem.AddDown(Value,Data,ROR(Hash));
          TLinkedItem(Items[i]).Free;
          Items[i]:=TreeItem;
        end else
          Items[i]:=TLinkedItem.Create(Value,Data,TLinkedItem(Items[i]));
      end;
    end;constructor TTreeItem.Create(AOwner: THashTable);
    var j: integer;
    begin
      Owner:=AOwner;
      Level:=0;
      Filled:=0;
      for j:=0 to LeafSize-1 do Items[j]:=nil;
    end;procedure TTreeItem.Delete(Value, Hash: DWORD);
    var i: integer;
        TreeItem: TTreeItem;
        PrevLinkedItem,LinkedItem: TLinkedItem;
    begin
      i:=Hash and $FF;
      if Items[i] = nil then begin
        Exit;
      end else if Items[i] is TTreeItem then begin
        TTreeItem(Items[i]).Delete(Value,ROR(Hash));
        if TTreeItem(Items[i]).Filled = 0 then begin
          TTreeItem(Items[i]).Free;
          Items[i]:=nil;
        end;
      end else begin
        PrevLinkedItem:=nil;
        LinkedItem:=TLinkedItem(Items[i]);
        while LinkedItem <> nil do begin
          if Owner.CompareValue(LinkedItem.Value,Value) then begin
            // found
            if PrevLinkedItem = nil then begin
              Items[i]:=LinkedItem.Next;
              if Items[i] = nil then
                Dec(Filled);
            end else
              PrevLinkedItem.Next:=LinkedItem.Next;
            LinkedItem.Next:=nil;
            Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data);
            LinkedItem.Free;
            Exit;
          end;
          PrevLinkedItem:=LinkedItem;
          LinkedItem:=LinkedItem.Next;
        end;
      end;
    end;destructor TTreeItem.Destroy;
    var j: integer;
        LinkedItem: TLinkedItem;
    begin
      for j:=0 to LeafSize-1 do
        if Items[j] <> nil then
          if Items[j] is TTreeItem then
            TTreeItem(Items[j]).Free
          else begin
            LinkedItem:=TLinkedItem(Items[j]);
            while LinkedItem <> nil do begin
              Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data);
              LinkedItem:=LinkedItem.Next;
            end;
            TLinkedItem(Items[j]).Free;
          end;
      inherited;
    end;function TTreeItem.Find(Value, Hash: DWORD; var Data: DWORD): Boolean;
    var i: integer;
        TreeItem: TTreeItem;
        LinkedItem: TLinkedItem;
    begin
      Result:=False;
      i:=Hash and $FF;
      if Items[i] = nil then begin
        Exit;
      end else if Items[i] is TTreeItem then begin
        Result:=TTreeItem(Items[i]).Find(Value,ROR(Hash),Data);
      end else begin
        LinkedItem:=TLinkedItem(Items[i]);
        while LinkedItem <> nil do begin
          if Owner.CompareValue(LinkedItem.Value,Value) then begin
            // found
            Data:=LinkedItem.Data;
            Result:=True;
            Exit;
          end;
          LinkedItem:=LinkedItem.Next;
        end;
      end;
    end;function TTreeItem.ROR(Value: DWORD): DWORD;
    begin
      Result:=((Value and $FF) shl 24) or ((Value shr 8) and $FFFFFF);
    end;function TTreeItem.RORN(Value: DWORD; Level: integer): DWORD;
    begin
      Result:=Value;
      while Level > 0 do begin
        Result:=ROR(Result);
        Dec(Level);
      end;
    end;function TTreeItem.Traverse(UserData,UserProc: Pointer;
      TraverseProc: TTraverseProc): Boolean;
    var j: integer;
        LinkedItem: TLinkedItem;
    begin
      Result:=False;
      for j:=0 to LeafSize-1 do
        if Items[j] <> nil then begin
          if Items[j] is TTreeItem then begin
            Result:=TTreeItem(Items[j]).Traverse(UserData,UserProc,TraverseProc);
          end else begin
            LinkedItem:=TLinkedItem(Items[j]);
            while LinkedItem <> nil do begin
              TraverseProc(UserData,UserProc,LinkedItem.Value,LinkedItem.Data,Result);
              LinkedItem:=LinkedItem.Next;
            end;
          end;
          if Result then Exit;
        end;
    end;{ TLinkedItem }constructor TLinkedItem.Create(FValue,FData: DWORD; FNext: TLinkedItem);
    begin
      Value:=FValue;
      Data:=FData;
      Next:=FNext;
    end;destructor TLinkedItem.Destroy;
    begin
      if Next <> nil then
        Next.Free;
    end;{ THashTable }procedure THashTable.AddDown(Value,Data,Hash: DWORD);
    begin
      if Root = nil then
        Root:=TTreeItem.Create(Self);
      Root.AddDown(Value,Data,Hash);
    end;procedure THashTable.Delete(Value,Hash: DWORD);
    begin
      if Root <> nil then
        Root.Delete(Value,Hash);
    end;function THashTable.Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
    begin
      if Root <> nil then
        Result:=Root.Find(Value,Hash,Data)
      else
        Result:=False;
    end;constructor THashTable.Create;
    begin
      inherited;
      Root:=nil;
    end;destructor THashTable.Destroy;
    begin
      if Root <> nil then Root.Free;
      inherited;
    end;procedure THashTable.Traverse(UserData, UserProc: Pointer;
      TraverseProc: TTraverseProc);
    begin
      if Root <> nil then
        Root.Traverse(UserData, UserProc, TraverseProc);
    end;{ TStringHashTable }procedure TStringHashTable.Add(const S: string; Data: TObject);
    begin
      AddDown(DWORD(NewStr(S)),DWORD(Data),HashStr(S));
    end;function TStringHashTable.CompareValue(Value1, Value2: DWORD): Boolean;
    begin
      if FCaseSensitive then
        Result:=PString(Value1)^ = PString(Value2)^
      else
        Result:=ANSICompareText(PString(Value1)^,PString(Value2)^) = 0;
    end;constructor TStringHashTable.Create;
    begin
      inherited;
      FCaseSensitive:=False;
      FAutoFreeObjects:=False;
    end;procedure TStringHashTable.Delete(const S: string);
    begin
      inherited Delete(DWORD(@S),HashStr(S));
    end;procedure TStringHashTable.DestroyItem(var Value,Data: DWORD);
    begin
      DisposeStr(PString(Value));
      if FAutoFreeObjects then
        TObject(Data).Free;
      Value:=0;
      Data:=0;
    end;function TStringHashTable.Find(const S: string; var Data: TObject): Boolean;
    begin
      Result:=inherited Find(DWORD(@S),HashStr(S),DWORD(Data));
    end;function TStringHashTable.HashStr(const S: string): DWORD;
    {var i: integer;}
    begin
      if CaseSensitive then
        Result:=CalcStrCRC32(S)
      else
        Result:=CalcStrCRC32(ANSIUpperCase(S));{ another hash fucn with good performance
      see code at the end of this unit
      if CaseSensitive then
        Result:=HashP2Str(S)
      else
        Result:=HashP2Str(ANSIUpperCase(S));
    }{ simple hash-func. don't use it !!!
      result:=Length(S);
      for i:=1 to Length(S) do
        if CaseSensitive then
          Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(S[i])
        else
          Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(ANSIUpperCase(S)[i]);
    }
    end;function TStringHashTable.HashValue(Value: DWORD): DWORD;
    begin
      Result:=HashStr(PString(Value)^);
    end;procedure TStringHashTable.Traverse(UserData: Pointer;
      UserProc: TStrHashTraverseProc);
    begin
      inherited Traverse(UserData,@UserProc,TraverseProc);
    end;procedure TStringHashTable.TraverseProc(UserData, UserProc: Pointer; Value,
      Data: DWORD; var Done: Boolean);
    begin
      TStrHashTraverseProc(UserProc)(UserData,PString(Value)^,TObject(Data),Done);
    end;procedure TStringHashTable.Traverse(UserData: Pointer; UserProc: TStrHashTraverseMeth);
    begin
      inherited Traverse(UserData,@TMethod(UserProc),TraverseMeth);
    end;procedure TStringHashTable.TraverseMeth(UserData, UserProc: Pointer; Value,
      Data: DWORD; var Done: Boolean);
    type
      PTStrHashTraverseMeth = ^TStrHashTraverseMeth;
    begin
      PTStrHashTraverseMeth(UserProc)^(UserData,PString(Value)^,TObject(Data),Done);
    end;{ dynamic crc32 table }const
      CRC32_POLYNOMIAL = $EDB88320;
    var
      Ccitt32Table: array[0..255] of DWORD;function CalcStrCRC32(const S: string): DWORD;
    var j: integer;
    begin
      Result:=$FFFFFFFF;
      for j:=1 to Length(S) do
        Result:= (((Result shr 8) and $00FFFFFF) xor (Ccitt32Table[(Result xor byte(S[j])) and $FF]));
    end;procedure BuildCRCTable;
    var i, j: longint;
        value: DWORD;
    begin
      for i := 0 to 255 do begin
        value := i;
        for j := 8 downto 1 do
          if ((value and 1) <> 0) then
            value := (value shr 1) xor CRC32_POLYNOMIAL
          else
            value := value shr 1;
        Ccitt32Table[i] := value;
      end
    end;initialization
      BuildCRCTable;
    end.